牛客网练习赛23 C 托米的位运算(贪心+位运算技巧)

本文介绍了一个算法问题,目标是在满足特定条件下最大化所选元素的数量。通过巧妙利用位运算和贪心策略,文章详细阐述了解决方案,并附带完整的源代码。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

链接:https://www.nowcoder.com/acm/contest/156/C
来源:牛客网
 

题目描述

托米完成了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

备注:

n≤ 105, a1... an < 231
#include<iostream>
#include<algorithm>
#include<string>
#include<map>//int dx[4]={0,0,-1,1};int dy[4]={-1,1,0,0};
#include<set>//int gcd(int a,int b){return b?gcd(b,a%b):a;}
#include<vector>
#include<cmath>
#include<stack>
#include<string.h>
#include<stdlib.h>
#include<cstdio>
#define mod 1e9+7
#define ll long long
#define maxn 100005
#define MAX 1000000000
#define ms memset
using namespace std;
/*
题目大意:(中文题目,不解释了)

这题主要是技巧,
一个是如何判断一个数是(1<<i)的呢?
需要用到树状数组里面的lowbit知识,
有了这个判定就方便多了
比赛时这题搞烦了,主要是对时间复杂度的不敏感
还特地用节点存储排了序,导致好多错误。。。。
仔细想想暴力一点就10^6的复杂度。

下面讨论里面的数学。
对于i位开头是1的所有数,
如果这些数中有任意两个相与其结果为(1<<i)
那么贪心可得,这个范围的数都可以选,但不能比这个小的任何数。

那么倒退i,让1<<i的范围倒退即可,逐步判断,一旦发现了一定是最佳的选择。
                                                    

*/
int data[maxn],n;
int ans[maxn],cnt=0;
int main()
{
    scanf("%d",&n);
    for(int i=1;i<=n;i++) scanf("%d",&data[i]);

    for(int i=30;i>=0;i--)
    {
        cnt=0;
        int s=(1ll<<31)-1;
        for(int j=1;j<=n;j++)
            if(data[j]>>i & 1) s&=data[j],ans[cnt++]=data[j];
        if( (s&-s)==(1<<i) ) break;
    }
    cout<<cnt<<endl;
     for(int i=0;i<cnt;i++)
     {
         if(i==0) cout<<ans[i];
         else cout<<" "<<ans[i];
     }
     cout<<endl;
    return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值