【題目描述】
任何一個正整數都可以用2的冪次方表示。例如:
137=27+23+20
同時約定方次用括號來表示,即ab可表示為a(b)。由此可知,137可表示為:
2(7)+2(3)+2(0)
進一步:7=22+2+20(21用2表示)
3=2+20
所以最后137可表示為:
2(2(2)+2+2(0))+2(2+2(0))+2(0)
又如:
1315=210+28+25+2+1
所以1315最后可表示為:
2(2(2+2(0))+2)+2(2(2+2(0)))+2(2(2)+2(0))+2+2(0)
【輸入】
一個正整數n(n≤20000)。
【輸出】
一行,符合約定的n的0,2表示(在表示中不能有空格)。
【輸入樣例】
137
【輸出樣例】
2(2(2)+2+2(0))+2(2+2(0))+2(0)
思路:
這道題的大體思路就是把所輸入的數全部用2進制數來表示,既然要用2進制的數把輸入的數拆分,就想到了用遞歸函數。
①先創建一個數組a,數組中的數的位置分別是2的幾次冪。因為輸入的數n小於等於20000也就是小於2^15,所以就創建數組15個數。
②先找出數組a中小於n的最大的數的位數k,之后對k分析。
③如果k=0、1、2分別輸出2(0)、2(1)、2(2)。
④如果k>2的話就說明輸出的數不能直接表達出來了,就要再次分解,所以先輸入2(),括號里的數需要再次分解,遞歸函數就可以了。
⑤考慮完分解的第一個數之后,就開始對第二個數開始分析,如果存在第二個數就輸出+,講n-第一個數的值放到函數中。隨后依次類推到沒有余數就結束了。
代碼:
#include <iostream> int a[15]; using namespace std; void two(int n) { int k; for (k = 14;k>=0;--k) { if (a[k] <= n) break; } if (k == 0) cout << "2(0)"; else if (k == 1) cout << "2"; else if (k == 2) cout << "2(2)"; else { cout << "2("; two(k); cout << ")"; } if (a[k] < n) { cout << "+"; two(n - a[k]); } } int main() { a[0] = 1; for (int i = 1;i < 15;++i) { a[i] = 2 * a[i - 1]; } int n; cin >> n; two(n); return 0; }