首页 > 其他 > 详细

POJ 2436 二进制枚举+位运算

时间:2015-05-05 23:14:02      阅读:298      评论:0      收藏:0      [点我收藏+]

题意:给出n头牛的得病的种类情况,一共有m种病,要求找出最多有K种病的牛的数目;

思路:二进制枚举(得病处为1,否则为0,比如得了2 1两种病,代号就是011(十进制就是3)),首先枚举出1的个数等于k的二进制数,然后跟所有的牛的代号一一比较,符合的           +1,找出其中和最大的;就是转换2进制麻烦,用位运算就好实现了,但是位运算不是很明白含义,明白了再补充;

知识点:

  1. 3 & 2 = 2,相同为1,不同为0, 011 & 010 = 010;(怎么利用的这个特点不明白);
  2. t |= (1 << (b - 1));表示t等于b转换成二进制后,再转换成十进制,就是或,相同为0,不同为1,在这里相当于二进制求和。
技术分享
 1 #include <iostream>
 2 #include <cstdlib>
 3 #include <cstring>
 4 #include <cstdio>
 5 using namespace std;
 6 #define maxn 1005
 7 int n, d, k;
 8 int cow[maxn];
 9 
10 int ok(int a)
11 {
12     int ret = 0;
13     while (a)
14     {
15         ret += (a & 1);
16         a >>= 1;
17     }
18     return ret == k;///如果a转换成二进制有k个1,返回k,否则返回0
19 }
20 
21 int main()
22 {
23     scanf("%d%d%d", &n, &d, &k);
24     for (int i = 0; i < n; i++)
25     {
26         int a, b;
27         scanf("%d", &a);
28         for (int j = 0; j < a; j++)
29         {
30             scanf("%d", &b);
31             cow[i] |= (1 << (b - 1));
32             cout<<cow[i]<<endl;
33             ///cow[i]表示牛得病的2进制表示,然后转换为十进制
34             ///如果1 2的话,就是010(cow[i] = 2),第二个位置是1
35             ///如果2 1 2的话,就是011(cow[i] = 3),第一二个位置是1
36         }
37     }
38     int s = (1 << k) - 1;
39     int e = s << (d - k);///即s*(2^(d-k))
40     int ans = 0;
41     for (int i = s; i <= e; i++)
42     {
43         if (ok(i))///如果该牛有k种病,进下一关
44         {
45             int temp = 0;
46             for (int j = 0; j < n; j++)///枚举每头牛,符合的加1
47             {
48                 ///不明白if
49                 if ((i & cow[j]) == cow[j])///都转化为2进制,按位与,二进制数只要小于i就满足
50                     temp++;
51             }
52             ans = max(ans, temp);
53         }
54     }
55     printf("%d\n", ans);
56     return 0;
57 }
View Code

 

POJ 2436 二进制枚举+位运算

原文:http://www.cnblogs.com/ACMERY/p/4480441.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!