1. 程式人生 > >An easy problem (位運算)

An easy problem (位運算)

amp using lowbit bsp 找到 要求 位置 return 代碼

【題目描述】

    給出一個整數,輸出比其大的第一個數,要求輸出的數二進制表示和原數二進制表示下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 (位運算)