[洛谷]P1010 幂次方
经典递归
拖动正文两侧的页边标记调整宽度,左右方向键也可调节,双击或按 Home 恢复默认宽度。
题目描述
任何一个正整数都可以用 的幂次方表示。例如 。
同时约定次方用括号来表示,即 可表示为 ( 为a的b次方)。
由此可知, 可表示为 。
进一步:
( 用 表示),并且 ,
所以最后 可表示为:2(2(2)+2+2(0))+2(2+2(0))+2(0)。
又如 ,
所以 最后可表示为:
。
整体思路
看到这道题,相信很多人都第一时间想到了递归。虽然很多大佬用二进制也能完成这道题,但是递归无疑是最容易理解的一种方式。 我们不妨定义一个函数 void print(int k){},用这个函数来打印出 的 的幂次方表示。
具体实现
我们从 开始尝试: 当 时,应输出 ” ”;
当 时,应输出 ” ”;
当 时,应输出 ” ”;
当 时,应输出 ” ”;
当 时,应输出 ” ”;
首先,我们发现输出的结果都是由“ ”和“ ”组成的,所以递归的终止条件就是 或 。
其次, 后,结果都是由多部分组成的(除了 的整数幂),所以不妨先利用循环枚举,将 分解为多个 的整数幂形式,存在数组中,以便输出。
最后,在输出前几项时,应紧跟着输出 '' ,而最后一项不需要输出 ''。
代码实现
#include <iostream>
#include <cstring>
using namespace std;
int pow[17]; // 存储2的所有整数幂的值,数据最大范围是2×10^4,而2^15约等于32768
void print(int k)
{
int t = 15;
int a[17]; // 存储k分解后的2的整数幂
int len = 0; // 计录数组a的长度
memset(a, 0, sizeof(a));
while (k > 0) // 循环将k分解为2的整数幂,并存入数组a中
{
if (k >= pow[t])
{
a[++len] = t; // 存入指数
k -= pow[t];
}
t--;
}
for (int i = 1; i <= len; i++) // 循环递归(最后一项不需要‘+’)
{
if (a[i] == 0) // 如果这一项指数为0,输出”2(0)“
cout << "2(0)";
else if (a[i] == 1) // 如果这一项指数为0,输出”2“
cout << "2";
else
{
cout << "2(";
print(a[i]); // 其他情况,输出"2(a[i])"
cout << ")";
}
if (i != len) // 最后一项不需要输出'+'
cout << '+';
}
return;
}
int main()
{
pow[0] = 1;
for (int i = 1; i <= 15; i++)
pow[i] = 2 * pow[i - 1]; // 提前计算2的整数幂,减少计算量
int n;
cin >> n;
print(n);
cout << endl;
return 0;
}