Newcoder 156 C.托米的位运算(贪心)

Description

托米完成了 1317 1317 1317的上一个任务,十分高兴,可是考验还没有结束

说话间 1317 1317 1317给了托米 n n n 个自然数 a 1 . . . a n a_1... a_n a1...an, 托米可以选出一些带回家,但是他选出的数需要满足一些条件

设托米选出来了$k 个 数 个数 b_1,b_2… b_k$, 设这个数列 b b b 的给值为 b b b 中所有数按位与的结果,如果你能找到一个整除 $b 的 最 大 的 的最大的 2v , , ,(v\ge 0)$, 则设定 v v v 为这个数列的给价,如果不存在这样的 v v v,则给价值为$ -1$, 1317 1317 1317 希望托米在最大化给价的情况下,最大化$ k$

Input

第一行输入一个整数$ n$, 第二行输入 a 1 . . . a n a_1...a_n a1...an

( n ≤ 1 0 5 , a 1 , . . . , a n < 2 31 ) (n\le 10^5,a_1,...,a_n<2^{31}) (n105,a1,...,an<231)

Output

第一行输出最大的整数 k k k, 第二行输出 k k k 个整数 b 1 . . . b k b_1... b_k b1...bk, 按原数列的相对顺序输出 (如果行末有额外空格可能会格式错误)

Sample Input

5
1 2 3 4 5

Sample Output

2
4 5

Solution

从大到小枚举 v v v,将第 v v v位都为 1 1 1的数字取出,若这些数字逻辑与后在第 v v v位后都是 0 0 0则说明 v v v合法,此时选取的数字显然最多

Code

#include
using namespace std;
#define maxn 100005
int n,a[maxn],ans[maxn],res;
int main()
{
	scanf("%d",&n);
	for(int i=1;i<=n;i++)scanf("%d",&a[i]);
	for(int v=30;v>=0;v--)
	{
		int temp=(1<>v)&1)temp=(temp&a[i]),ans[res++]=i;
		if(temp==0)
		{
			printf("%d\n",res);
			for(int i=0;i

你可能感兴趣的:(Newcoder,贪心)