托米的位运算

链接:https://ac.nowcoder.com/acm/problem/16762
来源:牛客网

题目描述
托米完成了1317的上一个任务,十分高兴,可是考验还没有结束
说话间1317给了托米 n 个自然数 a1... an, 托米可以选出一些带回家,但是他选出的数需要满足一些条件
设托米选出来了k 个数 b1,b2... bk, 设这个数列 b 的给值为 b 中所有数按位与的结果,如果你能找到一个整除 b 的最大的 2v,(v≥ 0), 则设定 v 为这个数列的给价,如果不存在这样的 v,则给价值为 -1, 1317 希望托米在最大化给价的情况下,最大化 k
输入描述:
第一行输入一个整数 n, 第二行输入 a1...an
输出描述:
第一行输出最大的整数 k, 第二行输出 k 个整数 b1... bk, 按原数列的相对顺序输出 (如果行末有额外空格可能会格式错误)
示例1
输入
复制
5
1 2 3 4 5
输出
复制
2
4 5
//看的大佬题解,大佬牛逼
//解释看代码注释

 //https://ac.nowcoder.com/acm/problem/16762
 //满足题意的b,在二进制中,有一位共同位都是1,然后这位数后边的应当不全为1,
 //不全为1时,&一下后变就变为0,也就不会产生余数,也就能整除了
 //此题要求b%2的v次=0; 
#include<bits/stdc++.h>
#define ll long long  
using namespace std;
const int N=1e5+100; 
#define ll long long
int a[N],s[N];
typedef pair<int,int> PII;
//typedef pair<int,int>PII;
vector<int>q;
int n,l,r;
int main()
{    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    cin>>n;
    for(int i=0;i<n;i++) cin>>a[i];
    for(int i=31;i>=0;i--)
    {
        q.clear();//记得每次判断后清空 
        int v=(1<<i),t=(1<<i)-1;//v也就是题中2的v次,在二进制中,只有一位是1
                                //左移31位,是int是32位,也就是最顶点变成1了
                                //t是用来判断自己所找的数中,v位后边的不全为0 
        for(int k=0;k<n;k++) //t中是第v位后边全为1,如果找的b里边低于v的某位 
        {                        //全为1,则t最后不等于0 
            if(a[k]&v) q.push_back(a[k]),t=t&a[k];        
        }
        if(t==0) break;//找到则break,这是最大的v 
    }
    cout<<q.size()<<endl;
    for(int i=0;i<q.size()-1;i++)
    {
        cout<<q[i]<<" ";
    }
    cout<<q[q.size()-1];
    return 0;
> }
全部评论

相关推荐

头像
点赞 评论 收藏
转发
点赞 收藏 评论
分享
牛客网
牛客企业服务