[NOIP1998 普及组] 幂次方
题目描述
任何一个正整数都可以用 2 2 2 的幂次方表示。例如 $137=27+23+2^0 $。
同时约定方次用括号来表示,即 a b a^b ab 可表示为 a ( b ) a(b) a(b)。
由此可知, 137 137 137 可表示为 2 ( 7 ) + 2 ( 3 ) + 2 ( 0 ) 2(7)+2(3)+2(0) 2(7)+2(3)+2(0)
进一步:
7 = 2 2 + 2 + 2 0 7= 2^2+2+2^0 7=22+2+20 ( 2 1 2^1 21 用 2 2 2 表示),并且 3 = 2 + 2 0 3=2+2^0 3=2+20。
所以最后 137 137 137 可表示为 2 ( 2 ( 2 ) + 2 + 2 ( 0 ) ) + 2 ( 2 + 2 ( 0 ) ) + 2 ( 0 ) 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 + 1 1315=2^{10} +2^8 +2^5 +2+1 1315=210+28+25+2+1
所以 1315 1315 1315 最后可表示为 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) 2(2(2+2(0))+2)+2(2(2+2(0)))+2(2(2)+2(0))+2+2(0)。
输入格式
一行一个正整数 n n n。
输出格式
符合约定的 n n n 的 0 , 2 0, 2 0,2 表示(在表示中不能有空格)。
样例 #1
样例输入 #1
1315
样例输出 #1
2(2(2+2(0))+2)+2(2(2+2(0)))+2(2(2)+2(0))+2+2(0)
提示
【数据范围】
对于 100 % 100\% 100% 的数据, 1 ≤ n ≤ 2 × 10 4 1 \le n \le 2 \times {10}^4 1≤n≤2×104。
这题真的麻了,最初的想法就是递归位运算,但是在从高位还是低位那里就开始混乱,看了洛谷上的题解,分的我也不是很明白。
最后y总还是yyds,4分钟搞定这道题呜呜呜。
思路:
就是递归加位运算,首先根据题目给的提示可以发现,最终的答案里面只有2和2(0)出现。
因此递归结束的条件就是i=0或者i=1,i是枚举的输入数字的二进制位数。
否则就递归处理当前位数。
通过数据范围可以推断(y总思路好棒),这样就不用去判断这个传入的数有多少位了。
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
string dfs(int u){
string res;
//n小于两万,写成二进制最多有15位,从最高位开始判断
for(int i=14;i>=0;i--){
if(u>>i&1){
if(res.size()) res+="+";//如果不是第一位需要有+连接
if(!i) res+="2(0)";
else if(i==1) res+="2";
else res+="2("+dfs(i)+")";
}
}
return res;
}
int main(){
int n;
cin>>n;
cout<<dfs(n)<<endl;
return 0;
}