CSP历年复赛题-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;
}
分类:
CSP-J复赛真题解析
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?