难度:普及-(普及/提高-)
题目类型:分治
提交次数:1
涉及知识:分治
题目描述
任何一个正整数都可以用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)
输入输出格式
输入格式:
一个正整数n(n≤20000)。
输出格式:
符合约定的n的0,2表示(在表示中不能有空格)
代码:
1 #include<iostream> 2 using namespace std; 3 int n; 4 int a[16]; 5 void solve(int x){ 6 int i = 0; 7 if(x){ 8 cout<<"2"; 9 while(x>=a[i]) 10 i++; 11 i--; 12 x-=a[i]; 13 if(i!=1) cout<<"("; 14 if(i == 0||i == 2) cout<<i<<")"; 15 if(i >= 3){ 16 solve(i); cout<<")"; 17 } 18 if(x!=0) { 19 cout<<"+"; solve(x); 20 } 21 } 22 return; 23 } 24 int main(){ 25 cin>>n; 26 int i; 27 a[0] = 1; 28 for(i = 1; i <= 15; i++) 29 a[i] = a[i-1]*2; 30 solve(n); 31 return 0; 32 }
备注:
to be honest。。这道题呢,就是我看了一遍某题解,又照着抄了一遍,并告诉自己只是通过这种方式熟悉一下分治思想……分析一下这道题的思路吧:大家都说题目已经把递归过程说的很清楚了。然而我……
比较巧妙的一点就是,因为给了n<=20000,所以就打表把2的1——15次方都存在数组a里了。思路是,只要待处理的数字不是0,就先把2打上,找出这个数字的最大幂(就是2的i次方),把最大幂减掉,然后下面就处理减掉的这部分,即最大幂。
只要不是1(是1就不用打了),二话不说先把“(”打上,如果是0或2,直接输出就行了,如果不是,就solve(i),然后最大幂这部分就finish了。
此时如果x还剩下,就先连接一个“+”,然后继续处理x。
思路似乎是挺清晰的。但递归特别让我头疼……可能多练练就好了吧