1010 幂次方

难度:普及-(普及/提高-)

题目类型:分治

提交次数: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。

思路似乎是挺清晰的。但递归特别让我头疼……可能多练练就好了吧

posted @ 2016-10-07 14:30  timeaftertime  阅读(347)  评论(0编辑  收藏  举报