题意:
给一个数组,一个数x,每次可以对一个数组元素进行操作:a[i]=a[i]&x。问最少进行几次操作,可以使得数组中存在两个相同的元素,也可以不进行操作。如果无法出现两个相同的元素,输出-1.
按位&的性质:
ans=m&x,那么ans=ans&x
也就是说,ans是m和x在二进制下的交集,ans再次和x进行交集运算,得到的数肯定不变。
题解
因为无论进行多少次&操作,都和进行一次是一样的,所以对于每个数,都只有进行&或者不进行两种情况。
那么答案就只有三种,0,1,2.
本来数组中就存在两个相同的元素,把一个元素进行操作。对两个元素进行操作。
#pragma warning(disable:4996)
#include<algorithm>
#include<cmath>
#include<iostream>
#include<cstdio>
#include<cstring>
#include<stack>
#include<vector>
#include<map>
#include<string>
#include<set>
#include<queue>
using namespace std;
typedef long long ll;
int vis[1000005], a[100005];
int main()
{
int n, x, i;
scanf("%d%d", &n, &x);
for (i = 1; i <= n; i++)
{
scanf("%d", &a[i]);
vis[a[i]]++;
if (vis[a[i]] >= 2)//已经有两个相同的元素
{
printf("0\n");
return 0;
}
}
for (i = 1; i <= n; i++)
{
if (vis[a[i] & x] == 1 && a[i] != (a[i] & x))
//因为进行&之后得到的结果可能和原来一样,比如6&7=6
//所以保证a[i]!=(a[i]&x)
{
printf("1\n");
return 0;
}
}
for (i = 1; i <= n; i++)
{
vis[a[i] & x]++;
if (vis[a[i] & x] >= 2 && a[i] != (a[i] & x))
{
printf("2\n");
return 0;
}
}
printf("-1\n");
return 0;
}