题目链接:https://www.luogu.com.cn/problem/P1010
题目描述:
任何一个正整数都可以用 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 的 0,2 表示(在表示中不能有空格)。
输入输出样例:
输入 #1
1315输出 #1
2(2(2+2(0))+2)+2(2(2+2(0)))+2(2(2)+2(0))+2+2(0)说明/提示
【数据范围】
对于 100% 的数据,1 ≤ n ≤ 2×10^4。
题目分析:
因为题目所给的数据最大不超过2万,所以还是比较好解决。
从题目说明和样例可以知道这道题大致是要用分治和递归去求解,将给定数字中最大的2的幂次方求出后再减去后再求出现在的最大的2的幂次方直至最后数字为0(求现在数字中最大的2的幂次方就体现出了分治的思想),再将所求得的最大幂次方分别进行处理,用递归判断其是否还能分成2的幂次方,最后把这些进行相加然后输出。
例如:7当中最大的2的幂次方为2^2,7减去4后为3,在3中最大的2的幂次方为2(2^1表示为2),3减去2后为1,在1中最大的2的幂次方为2^0,然后结束。
分析过后一步步进行解决!
代码片段:
int calculate(int n)//计算幂次方 { if (n == 0)//递归退出条件 return 0; int i, k = 1, count = 0;//i和count为幂函数的指数部分,i为大于所求数字的最小的2的幂次方的指数,count为所求数字中的2的最大的幂次方的指数 for (i = 1; i <= 15; i++) { k *= 2; count = i; if (k > n) { n -= k / 2;//当前n的值减去2的最大幂次方的值(因为2多乘了一次因此要/2) count--; break; } } if (n)//如果n有剩余继续分成小部分然后相加 { cout << "+";//所分成的小部分相加 return calculate(n);//继续处理剩余n的值 } return 0; }
代码分析:因为2的15次方为32768超出了所给范围,因此所求的最大的2的幂次方为2^14,因此1 < i <= 15,而count则大于0,小于等于14 ,假设给定数字为30,i就为5,因为2^5为32大于30,count为4,因为2^4为16小于30,30-16=14>0,因此继续分成其他小部分,直至数字变为0,但是如果count比较大就像4还可以看成2^2,这时该怎么办呢?不急,在后面加上递归的条件就行了,我用的是选择语句。
switch (count) { case 0:cout << "2(0)"; break; case 1:cout << "2"; break; default:cout << "2("; calculate(count); cout << ")"; break;//指数为其他情况时 }
在for循环和if判断中间加上switch语句,判断是否需要递归。
整体代码(已AC):
#include <iostream>
using namespace std;
int calculate(int n)//计算幂次方
{
if (n == 0)//n为0时退出
return 0;
int i, k = 1, count = 0;//i和count为幂函数的指数部分
for (i = 1; i <= 15; i++)
{
k *= 2;
count = i;
if (k > n)
{
n -= k / 2;//当前n的值减去2的最大幂次方的值
count--;
break;
}
}
switch (count)
{
case 0:cout << "2(0)"; break;
case 1:cout << "2"; break;
default:cout << "2("; calculate(count); cout << ")"; break;//指数为其他情况时
}
if (n)//如果n有剩余继续分成小部分然后相加
{
cout << "+";//所分成的小部分相加
return calculate(n);//继续处理剩余n的值
}
return 0;
}
int main()
{
int num;
cin >> num;//输入想处理的数据
calculate(num);
return 0;
}
本题简单体现出分治和递归的思想。如果有问题,可以进行讨论交流。
计算机204 zjr