洛谷题单指南-递推与递归-P1010 [NOIP1998 普及组] 幂次方
原题链接:https://www.luogu.com.cn/problem/P1010
题意解读:输出一个正整数的 的幂次方表示,需要用到二进制数学知识,将整数拆解成2的次幂之和,幂次方也要进行拆解,因此容易想到通过递归处理。
解题思路:
先看样例,给定整数137,要拆解成2的幂次方之和,
先考虑i使得刚好137>=2^i时,i取7,因此2^7是一个因子,137-2^7 = 137 - 128 = 9
再考虑i使得刚好9>=2^i时,i取3,因此2^3是一个因子,9 - 2^3 = 9 - 8 = 1
最后考虑i使得刚好1>=2^i时,i取0,因此2^0是一个因子,1 - 2^0 = 1 - 1 = 0
这样就完成了拆解137 = 2^7 + 2^3 + 2^0
因为整数最大是20000,因此每次在遍历找到第一个i时,可以从i=15开始递减,因为2^15 = 32768 > 20000 > 2^14 = 16384
要按格式输出结果,就需要递归处理
具体递归过程请参考代码注释。
100分代码:
#include <bits/stdc++.h>
using namespace std;
int n;
int pow2[20]; //预计算2^i,pow2[i]表示2^i
//预计算pow2[20]
void init()
{
int num = 1;
pow2[0] = num;
for(int i = 1; i <= 20; i++)
{
num *= 2;
pow2[i] = num;
}
}
//递归处理
void decode(int x)
{
if(x == 0) //是0的时候就不需要拆解成2的次方了,直接输出
{
cout << "0";
return;
}
for(int i = 15; i >=0; i--) //由于最大值是20000,要将x拆解多个2的次方之和,从2^15开始看是否够减,依次往后看
{
if(x >= pow2[i])
{
cout << "2";
if(i != 1) //如果2^1,则直接输出2即可,不需要(1)
{
cout << "(";
decode(i);
cout << ")";
}
x -= pow2[i];
break; //只需要找第一个满足要求的i,剩下的交给递归处理
}
}
if(x > 0) //如果x减去2^i之后不为0,继续递归处理剩下的部分
{
cout << "+"; //+加上剩下的部分
decode(x);
}
}
int main()
{
init(); //先预计算出2^i,存入pow2[20],便于后面使用
cin >> n;
decode(n);
return 0;
}