1. 程式人生 > >洛谷P1010 冪次方 題解

洛谷P1010 冪次方 題解

題目描述

任何一個正整數都可以用22的冪次方表示。例如

137=2^7+2^3+2^0137=27+23+20

同時約定方次用括號來表示,即a^bab 可表示為a(b)a(b)。

由此可知,137137可表示為:

2(7)+2(3)+2(0)2(7)+2(3)+2(0)

進一步:

7= 2^2+2+2^07=22+2+20(2^1用2表示),並且

3=2+2^03=2+20

所以最後137137可表示為:

2(2(2)+2+2(0))+2(2+2(0))+2(0)2(2(2)+2+2(0))+2(2+2(0))+2(0)

又如:

1315=2^{10} +2^8 +2^5 +2+11315=210+28+25+2+1

所以13151315最後可表示為:

2(2(2+2(0))+2)+2(2(2+2(0)))+2(2(2)+2(0))+2+2(0)2(2(2+2(0))+2)+2(2(2+2(0)))+2(2(2)+2(0))+2+2(0)

輸入輸出格式

輸入格式:

一個正整數n(n≤20000)n(n20000)。

輸出格式:

符合約定的nn的0,20,2表示(在表示中不能有空格)

輸入輸出樣例

輸入樣例#1:
1315
輸出樣例#1:
2(2(2+2(0))+2)+2(2(2+2(0)))+2(2(2)+2(0))+2+2(0)

題解

經典的分治題,大問題化小問題遞迴求解。

遞迴過程:

n做引數m,把2^m從大到小劃分為t個2^ai,m = 137時,次數分別為7、3、0,及2^138=2^7+2^3+2^0;

然後把7、3、0分別做引數m執行重複操作(遞迴)

m = 1輸出2

m = 0輸出0,由於0不能脫離"()"而單獨存在,所以定義在函式開頭

#include <iostream>
#include <cmath>
using namespace std;
int n;
void fz(int m) {
    if (m == 0) { 
        cout << "0"
; return; } int t = 0; int a[101]; while (m != 0) { int h = 0; while (1 << h <= m) h++; t++; a[t] = h - 1; m -= pow(2, h - 1); } for (int i = 1; i <= t; i++) { if (i != t) { if (a[i] == 1) { cout << "2+"; } else { cout << "2("; fz(a[i]); cout << ")+"; } } else { if (a[i] == 1) { cout << "2"; } else { cout << "2("; fz(a[i]); cout << ")"; } } } } int main() { cin >> n; fz(n); system("pause"); return 0; }