首页 > 代码库 > 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 }
注:数组开35的话,过不了最后一组用列,很迷。
51nod 1315 合法整数集 (位操作理解、模拟、进制转换)
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。