现在要求从中选出一些数作为b1, b2, b3... bm (m为选出的数的个数)
使得 b1 & b2 & b3 ... & bm的二进制末尾0的数量最大, 在满足这个值最大的同时如果有多个答案, 输出使得m尽量大的解, 如果依旧有多组解输出任意一组。
题解:
二进制数最多30位,直接枚举最高不为0 位,然后又是&运算 有0为0 只需要保证枚举的当前位置所有为1的全部拿下, 且拿下的数字中,比当前位置小的位在拿下的数字中至少要有一个为0。
代码:
#include<stdio.h>
#include<string.h>
int value[100005], w[100005];
int main()
{
int n, mark[32], num, coun, date;
while(scanf("%d", &n) != EOF)
{
for(int i = 1; i <= n; i++)
scanf("%d", &value[i]);
for(int i = 30; i >= 0; i--)
{
memset(mark, 0, sizeof(mark));
memset(w, 0, sizeof(w));
num = 0, coun = 0;
for(int j = 1; j <= n; j ++)
{
int k = 1 << (i-1);
if(value[j] & k)
{
int k1 = value[j];
w[coun ++] = value[j], date = 0;
while(k1)
{
int p = k1 % 2;
if(!p && !mark[date] && date < i)
num ++, mark[date] = 1;
date ++, k1 /= 2;
}
}
}
if(num == i-1) break;
}
printf("%d\n", coun);
printf("%d", w[0]);
for(int i = 1; i < coun; i++)
printf(" %d", w[i]);
printf("\n");
}
}