An easy problem (位运算)

Posted willendless

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了An easy problem (位运算)相关的知识,希望对你有一定的参考价值。

【题目描述】

    给出一个整数,输出比其大的第一个数,要求输出的数二进制表示和原数二进制表示下1的个数相同。

【题目链接】

    http://noi.openjudge.cn/ch0406/1455/

【算法】

    1、自己想的:设原数为n,从lowbit(n)开始左移找到第一个0的位置,同时记录该位置之前1的个数,将该位置置1,然后把1全堆在最后;如果找不到该位置,则该数是形如111100000...的样式,故将其左移一位,再把1堆在最后。感觉不够清晰。

    2、借鉴网上题解,比我清晰很多:直接给原数加上lowbit(n),再把1堆在最后,结束。。。而且堆在最后也可以简洁的用位运算:(n^(n+lowbit(n)))/lowbit(n)>>2(原来lowbit(n)前有x个1,异或之后有x+1个1,应该堆x-1个1,所以右移两位)。。。不过用时都是2ms。。。时间都耗在cin上了吧。。。。

【代码1】

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 int a,b,rec,num,ans;
 4 int main()
 5 {
 6     while(cin>>a&&a) {
 7         rec=num=0;
 8         b=a&-a;
 9         while(b<=a&&!rec) {
10             if(!(a&b)) rec=b;
11             else num++;
12             b<<=1;
13         }
14         num--;
15         if(!rec) {
16             ans=b+(1<<num)-1;
17         }
18         else {
19             rec=-rec;
20             ans=a&rec;
21             ans+=(-rec);
22             ans+=(1<<num)-1;
23         }
24         cout<<ans<<endl;
25     }
26     return 0;
27 }

【代码2】

#include <bits/stdc++.h>
using namespace std;
int a;
int main()
{
    while(cin>>a&&a) {
        cout<<a+(a&-a)+((a^(a+(a&-a)))/(a&-a)>>2)<<endl;
    }
    return 0;
}

 

以上是关于An easy problem (位运算)的主要内容,如果未能解决你的问题,请参考以下文章

poj2826 An Easy Problem?!

POJ 2826 An Easy Problem? 判断线段相交

An easy problem

an easy problem(贪心)

D - An easy problem

An easy problem