K13613 相同个数的1加强版

题目描述

众所周知,在计算机中数据是以二进制的形式存储的。现在给定一个正整数x(1≤x≤10^8),你的任务是找到一个正整数y,y是大于x的最小的那个数,而且要求y和x的二进制形式中1的个数是一样的。

例如,n=78,那么n的二进制为“1001110”,二进制形式中1的个数为4,那么能满足条件的m是83,83二进制数是“1010011”,83是比78大的最小的那个数而且二进制中有4个1。

输入格式

第1行:一个整数N,表示有N组数据。

第2行:N个空格分隔的正整数x。

输出格式

N行:对于每个x输出一个整数y,y是大于x的最小的数,且y和x的二进制中1的数量相同。

输入输出样例

输入样例1:
5 1 2 3 4 78
输出样例1:
2 4 5 8 83

说明

【数据范围】

1 <= N <= 2 * 10^6; 1 <= x <= 10^8

【耗时限制】1000ms 【内存限制】128MB

不算难题,关键是对位运算的熟练度

代码:

#include <iostream>
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
LL n,x;
LL count(LL n){
    LL cnt=0;
    while(n){
        cnt++;
        n&=n-1;
    }
    return cnt;
}
int main()
{
    scanf("%lld",&n);
    while(n--){
        scanf("%lld",&x);
        LL y=(x&-x)+x;
        LL c=count(x)-count(y);
        y|=(1<<c)-1;
        printf("%lld\n",y);
    }
    return 0;
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值