這題是寧波區域賽的熱省賽中的一題……
后來偶然發現時POJ上的,而且有人用位運算搞過了,于是就去學位運算,通過Matrix67大牛的三篇文章學的,第四篇還沒看,(想看的可以去搜下Matrix67或者去我前面的文章找下,應該是sgu那篇,可以找到鏈接)
這題可以這么想,比如原數x=0101110的下一個是01100011,你可以這樣想,以要比原數大,必須把原數的最右邊的一段1(連續的,如果只有一個的,就是一個)變成0,把這段1的右邊的第一個0變成1,然后再在所得的數的最右邊補1,知道1的位數一樣。
這樣的話,我們就可以這樣做了
設原數為x
然后t = x + (x & -x);//(x & -x) 取x的最右邊的一個1,因為"把原數的最右邊的一段1變成0"可以加上最右邊一個1
接下來就是補1的過程了,當然可能不用補
好吧我們用一個函數得到x(10進制)在2進制表示下的1的個數(如果有看不懂的,建議先看下Matrix67大牛的位運算在看,當然到那個時候基本你自己也可以寫了,不必要看我的了,呵呵)
函數如下

get
1
int get(int n)
2

{
3
n = (n & 0x55555555) + ((n >> 1) & 0x55555555);
4
n = (n & 0x33333333) + ((n >> 2) & 0x33333333);
5
n = (n & 0x0F0F0F0F) + ((n >> 4) & 0x0F0F0F0F);
6
n = (n & 0x00FF00FF) + ((n >> 8) & 0x00FF00FF);
7
n = (n & 0x0000FFFF) + ((n >> 16) & 0x0000FFFF);
8
return n;
9
}
這樣我們就基本是完成了。具體代碼如下,個人建議先自己想,實在想不出來之后再看我的代碼

CODE
1
/**//*
2
ID:Klion
3
PROG:POJ_2453
4
LANG:C++
5
*/
6
#include <iostream>
7
using namespace std;
8
int get(int n)
9

{
10
/**//*
11
這里是錯的,因為這樣的話,會錯位,具體可以自己
12
手動算一下,可以用這個數11010011(211)
13
n = (n & 0xAAAAAAAA) + ((n >> 1) & 0xAAAAAAAA);
14
n = (n & 0xCCCCCCCC) + ((n >> 2) & 0xCCCCCCCC);
15
n = (n & 0xF0F0F0F0) + ((n >> 4) & 0xF0F0F0F0);
16
n = (n & 0xFF00FF00) + ((n >> 8) & 0xFF00FF00);
17
n = (n & 0xFFFF0000) + ((n >> 16) & 0xFFFF0000);
18
*/
19
n = (n & 0x55555555) + ((n >> 1) & 0x55555555);
20
n = (n & 0x33333333) + ((n >> 2) & 0x33333333);
21
n = (n & 0x0F0F0F0F) + ((n >> 4) & 0x0F0F0F0F);
22
n = (n & 0x00FF00FF) + ((n >> 8) & 0x00FF00FF);
23
n = (n & 0x0000FFFF) + ((n >> 16) & 0x0000FFFF);
24
return n;
25
}
26
int main(void)
27

{
28
int x;
29
int t,b,c;
30
while(scanf("%d",&x),x)
31
{
32
c = x & -x;
33
t = x + c;
34
b = get(x) - get(t);
35
t = t | ((1 << b) - 1);
36
printf("%d\n",t);
37
}
38
return 0;
39
}
40
后來偶然發現時POJ上的,而且有人用位運算搞過了,于是就去學位運算,通過Matrix67大牛的三篇文章學的,第四篇還沒看,(想看的可以去搜下Matrix67或者去我前面的文章找下,應該是sgu那篇,可以找到鏈接)
這題可以這么想,比如原數x=0101110的下一個是01100011,你可以這樣想,以要比原數大,必須把原數的最右邊的一段1(連續的,如果只有一個的,就是一個)變成0,把這段1的右邊的第一個0變成1,然后再在所得的數的最右邊補1,知道1的位數一樣。
這樣的話,我們就可以這樣做了
設原數為x
然后t = x + (x & -x);//(x & -x) 取x的最右邊的一個1,因為"把原數的最右邊的一段1變成0"可以加上最右邊一個1
接下來就是補1的過程了,當然可能不用補
好吧我們用一個函數得到x(10進制)在2進制表示下的1的個數(如果有看不懂的,建議先看下Matrix67大牛的位運算在看,當然到那個時候基本你自己也可以寫了,不必要看我的了,呵呵)
函數如下


1

2



3

4

5

6

7

8

9

這樣我們就基本是完成了。具體代碼如下,個人建議先自己想,實在想不出來之后再看我的代碼


1


2

3

4

5

6

7

8

9



10


11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27



28

29

30

31



32

33

34

35

36

37

38

39

40
