[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。
所需变量:
int i;//循环变量int j;//循环变量
int num;//代表所需要求展开式的数
思路:我们首先要判断这个数是否能展开,如果能展开的情况下要考虑他后面是否还有数字能展开,如果能展开我们就要加括号(),将后面能展开的都括号起来!然后循环不断地调用递归!
所调用的递归代码如下:
int solution(int &num){
int i,j;
if(num == 1){
cout<<"2(0)";
}else if(num == 2){
cout<<"2";
}else{
i = 2;
while(pow(2,i)<num){
i++;
}
for(j = i;j>=0;j--){
if(num>pow(2,j)){
if(j == 1){
num -=pow(2,j);
cout<<"2+";
}else{
num -=pow(2,j);
cout<<"2(";
solution(j);
cout<<")+";
}
}else if(num == pow(2,j)){
if(num == 1){
num = 0;
cout<<"2(0)";
}else if(num == 2){
num = 0;
cout<<"2";
}else{
num = 0;
cout<<"2(";
solution(j);
cout<<")";
}
}
}
}
}
上面这个代码的递归过程和思路都是完全没有问题的,我也是思索了很久也没有找到错误所在!
后来发现我把j当成变量传入下次了,那么当j再下一次递归的时候被改变,那么我们返回回来之后,j就发生改变了!这不是我们想要的答案!,因此我们就该定义一个变量记录下当时的j。这样就不会出错了!
正确代码在下面!
错误示范
#include<iostream>
using namespace std;
#include<math.h>
int solution(int &num){
int i,j;
if(num == 1){
cout<<"2(0)";
}else if(num == 2){
cout<<"2";
}else{
i = 2;
while(pow(2,i)<num){
i++;
}
for(j = i;j>=0;j--){
if(num>pow(2,j)){
if(j == 1){
num -=pow(2,j);
cout<<"2+";
}else{
num -=pow(2,j);
cout<<"2(";
solution(j);
cout<<")+";
}
}else if(num == pow(2,j)){
if(num == 1){
num = 0;
cout<<"2(0)";
}else if(num == 2){
num = 0;
cout<<"2";
}else{
num = 0;
cout<<"2(";
solution(j);
cout<<")";
}
}
}
}
}
int main(){
int num;
cin>>num;
solution(num);
return 0;
}
完整代码如下(编译器是dev,语言是C语言):
正确答案:
#include<iostream>
using namespace std;
#include<math.h>
int solution(int &num){
int i,j;
if(num == 1){
cout<<"2(0)";
}else if(num == 2){
cout<<"2";
}else{
i = 2;
while(pow(2,i)<num){
i++;
}
for(j = i;j>=0;j--){
if(num>pow(2,j)){
if(j == 1){
num -=pow(2,j);
cout<<"2+";
}else{
num -=pow(2,j);
cout<<"2(";
int t = j;
solution(j);
j = t;
cout<<")+";
}
}else if(num == pow(2,j)){
if(num == 1){
num = 0;
cout<<"2(0)";
}else if(num == 2){
num = 0;
cout<<"2";
}else{
num = 0;
cout<<"2(";
int t = j;
solution(j);
j = t;
cout<<")";
}
} }
}
}
int main(){
int num;
cin>>num;
solution(num);
return 0;
}