码迷,mamicode.com
首页 > 其他好文 > 详细

An easy problem (位运算)

时间:2018-07-22 14:01:58      阅读:175      评论:0      收藏:0      [点我收藏+]

标签:整数   很多   its   pac   std   clu   cin   记录   网上   

【题目描述】

    给出一个整数,输出比其大的第一个数,要求输出的数二进制表示和原数二进制表示下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 (位运算)

标签:整数   很多   its   pac   std   clu   cin   记录   网上   

原文地址:https://www.cnblogs.com/Willendless/p/9349798.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!