您的位置:首页 > 其它

51nod 1315 合法整数集

2016-03-27 23:20 218 查看
一个整数集合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


思路:如果一个数的二进制某一位是1并且x的这一位是0,则这个数就不用管了,

然后所求的答案就是剩下的数中二进制中值和x一样都为1的个数的最小值;(有点讲的不清楚,直接看代码吧)

#include <iostream>
#include <cstring>
#include <cstdlib>
#include <cstdio>
#include <string>
#include <cmath>
#include <set>
#include <queue>
#include <algorithm>
#include <vector>
#include <map>
using namespace std;
#define esp 1e-8
const double PI = acos(-1.0);
const int inf = 1000000005;
const long long mod = 1000000007;
//freopen("in.txt","r",stdin); //输入重定向,输入数据将从in.txt文件中读取
//freopen("out.txt","w",stdout); //输出重定向,输出数据将保存在out.txt文件中
int a[55], b[33], vis[55];
int main()
{
int n, x, i, j;
while (~scanf("%d%d", &n, &x))
{
for (i = 1; i <= n; ++i)
scanf("%d", &a[i]);
memset(b, 0, sizeof(b));
int mm = 100;
int s = 0;
memset(vis, 0, sizeof(vis));
for (i = 0; i <= 30; ++i)
{
if ((1 << i) > x)
break;
if (!((1 << i) &x))
{
for (j = 1; j <= n; ++j)
{
if (a[j] & (1 << i))
{
vis[j] = 1;
}
}
}
}
for (i = 0; i <= 30; ++i)
{
if ((1 << i) > x)
break;
if ((1 << i) & x)
{
s += (1 << i);
for (j = 1; j <= n; ++j)
{
if (((a[j] & (1 << i))) && (a[j] <= x) && !vis[j])
{
b[i] ++;
}
}
mm = min(mm, b[i]);
}
}
printf("%d\n", mm);
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: