首页 > 代码库 > 51nod 1315 合法整数集 (位操作理解、模拟、进制转换)

51nod 1315 合法整数集 (位操作理解、模拟、进制转换)

1315 合法整数集技术分享
题目来源: TopCoder
基准时间限制:1 秒 空间限制:131072 KB 分值: 10 难度:2级算法题
技术分享 收藏
技术分享 关注
技术分享 取消关注
一个整数集合S是合法的,指S的任意子集subS有Fun(SubS)!=X,其中X是一个固定整数,Fun(A)的定义如下:
A为一个整数集合,设A中有n个元素,分别为a0,a1,a2,...,an-1,那么定义:Fun(A)=a0 or a1 or ... or an-1;Fun({}) = 0,即空集的函数值为0.其中,or为或操作。
现在给你一个集合Y与整数X的值,问在集合Y至少删除多少个元素能使集合Y合法?
 
例如:Y = {1,2,4},X=7;显然现在的Y不合法,因为 1 or 2 or 4 = 7,但是删除掉任何一个元素后Y将合法。所以,答案是1.
Input
第一行两个整数N,X,其中N为Y集合元素个数,X如题所述,且1<=N<=50,1<=X<=1,000,000,000.
之后N行,每行一个整数yi,即集合Y中的第i个元素,且1<=yi<=1,000,000,000.
Output
一个整数,表示最少删除多少个元素。
Input示例
5 7
1
2
4
7
8
Output示例
2

首先找出经或操作后能合成x的整数a,在a的二进制表示下的数位值为1的数位属于在x的二进制表示下的数位值为1的数位的集合的子集。
然后用w[i]来存储不同数位的1的数量,取w[i]中的最小值即可。

技术分享
 1 #include <iostream>
 2 #include <cstring>
 3 using namespace std;
 4 #define INF 0x3f3f3f3f
 5 int w[55];
 6 int vis[55];
 7 int valid[55];
 8 int x,n;
 9 int a[55],b[55];
10 int main()
11 {
12     ios::sync_with_stdio(false);
13     while(cin>>n>>x)
14     {
15         memset(valid,0,sizeof(valid));
16         int pos=0;
17         while(x)
18         {
19             valid[pos++]=x%2;
20             x/=2;
21         }
22         memset(vis,0,sizeof(vis));
23         memset(w,0,sizeof(w));
24         for(int i=0;i<n;i++)
25         {
26              cin>>a[i];
27              int tmp=a[i];
28              int d=0;
29              while(tmp)
30              {
31                  b[d++]=tmp%2;
32                  tmp/=2;
33                  if(b[d-1]&&!valid[d-1])
34                     vis[i]=1;
35              }
36         }
37         int ans=INF;
38         for(int i=0;i<n;i++)
39         {
40             if(vis[i]) continue;
41             int tmp=a[i];
42             int d=0;
43             while(tmp)
44             {
45                 w[d++]+=tmp%2;
46                 tmp/=2;
47             }
48         }
49         for(int i=0;i<pos;i++)
50         {
51             if(!valid[i]) continue;
52             ans=min(w[i],ans);
53         }
54         ans=ans==INF?0:ans;
55         cout<<ans<<endl;
56     }
57     return 0;
58 }
View Code

注:数组开35的话,过不了最后一组用列,很迷。

51nod 1315 合法整数集 (位操作理解、模拟、进制转换)