1. 程式人生 > >2的n次冪

2的n次冪

初始化 表示 style 左移 splay pac pla opened 條件

問題描述

任何一個正整數都可以用2進制表示,例如:137的2進制表示為10001001。
  將這種2進制表示寫成2的次冪的和的形式,令次冪高的排在前面,可得到如下表達式:137=2^7+2^3+2^0
  現在約定冪次用括號來表示,即a^b表示為a(b)
  此時,137可表示為:2(7)+2(3)+2(0)
  進一步:7=2^2+2+2^0 (2^1用2表示)
  3=2+2^0
  所以最後137可表示為:2(2(2)+2+2(0))+2(2+2(0))+2(0)
  又如:1315=2^10+2^8+2^5+2+1
  所以1315最後可表示為:
  2(2(2+2(0))+2)+2(2(2+2(0)))+2(2(2)+2(0))+2+2(0)


輸入格式
  正整數(1<=n<=20000)
輸出格式
  符合約定的n的0,2表示(在表示中不能有空格)
樣例輸入
137
樣例輸出
2(2(2)+2+2(0))+2(2+2(0))+2(0)
樣例輸入
1315
樣例輸出
2(2(2+2(0))+2)+2(2(2+2(0)))+2(2(2)+2(0))+2+2(0)


思路

  簡單點的話,老老實實算二進制,再輸出;這裏涉及到每位二進制的指數也要一起分解,即在分解我們的數的途中還要分解,明顯的遞歸。

  但是也可以不用算出二進制,使用位運算直接對二進制進行操作,這裏用 137 來演示,具體如下:

  首先我們知道 137 的二進制為:10001001

1、獲取最高位二進制

1 for
(e=0, now=1; now <= n; now<<=1, e++);

這裏的 e 表示當前二進制的位置,也就是我們需要的指數,初始化為 0 位;now 表示 2 的 n 次方,用來與我們輸入的數 n 相比較,判斷具體要移動多少位。這裏我們循環結束後應該是這樣子的:

010001001  原數 137

100000000  2 的 8 次方 256

此時, e = 8, now = 256

2、判斷當前位是否是 0 位

這是大概最精彩的部分

1 for(;now>0;now>>=1, e--){
2         if(now & n){
      // 繼續
3   }

之前我們已經知道了 now 和 n 的二進制,接下來,當循環條件滿足時,我們就不斷將二進制左移(e--),同時將 now 與 n 按位與,得到如下結果:

010001001  原數 137

100000000  2 的 8 次方 256

000000000  0

判斷條件為假,繼續下一次循環:

010001001  原數 137

010000000  2 的 7 次方 128,因為我們右移了一位

010000000  此時不為0

判斷條件為真,繼續執行下面的內容,直到把當前的二進制讀取完。

下一次循環結果為

010001001  原數 137

001000000  2 的 6 次方 64

000000000  此時為0

一直下去......

3、判斷輸出

 1 void fun(int n)
 2 {
 3     int now, e;
 4     for(e=0, now=1; now <= n; now<<=1, e++);
 5     cout<<"2";
 6     for(;now>0;now>>=1, e--){
 7         if(now&n){
 8             if(now > 2){      // now 大於2,說明指數大於2,還要繼續分解
 9                 cout<<"(";
10                 fun(e);       // 遞歸
11                 cout<<")";
12             }
13             if(now == 2);      // 等於2時題目叫我們什麽也不做
14             else if(now == 1){    // 等於1是要輸出指數0
15                 cout<<"(0)";
16             }
17             /*
18             當當前指數分解結束後,要用之前的數減去當前分解的指數,比            
19             如這裏137 = 2^7 + 2^3 + 2^0,在分解完2^7後,繼續分解 
20             2^3 + 2^0
21             */
22             n -= now;        
23             if(n){         // 當然,如果可以繼續分解的話,否則這裏條件判斷是假
24                 cout<<"+2";
25             }
26         }
27     }
28 }                          

完整代碼

技術分享圖片
 1 #include<iostream> 
 2 
 3 using namespace std;
 4 
 5 void fun(int n)
 6 {
 7     int now, e;
 8     for(e=0, now=1; now <= n; now<<=1, e++);
 9     cout<<"2";
10     for(;now>0;now>>=1, e--){
11         if(now&n){
12             if(now > 2){
13                 cout<<"(";
14                 fun(e);
15                 cout<<")";
16             }
17             if(now == 2);
18             else if(now == 1){
19                 cout<<"(0)";
20             }
21             n -= now;
22             if(n){
23                 cout<<"+2";
24             }
25         }
26     }
27 }
28 int main()
29 {
30     int n = 0;
31     cin>>n;
32     fun(n);
33     
34     return 0;
35 }
View Code


2的n次冪