1.题目链接
2.题意描述
输入一个整数n,判断此数是否能被分解为若干个不同的2的正整数次幂,若能够则需要从大到小输出拆分中的每个数,若不能则输出-1。
注:上方被加粗的两个词语
(1)不同:拆分中的每个数字不可以相同,即2的次幂也不可相同
(2)正整数:大于0的整数,即拆分中不得出现1(
2
0
2^0
20)
3.样例解读
- 样例1中,输入的数字6,可以被拆分为 2 2 + 2 1 2^2+2^1 22+21,其为优秀的拆分,所以输出4 2
- 样例2中,输入的数字7,由于被拆分为 2 2 + 2 1 + 2 0 2^2+2^1+2^0 22+21+20,因为上方提到拆分中不得出现1,所以输出-1
4.解题思路
- 首先根据优秀的拆分规则:此数能被分解为若干个不同的2的正整数次幂轻松可以得出此数如果是优秀的拆分,其一定不是奇数,此步骤至少可以拿到20分。
- 其余偶数,我们对于2的正整数次幂中的次幂进行从大到小逐一遍历,由于题目中提到对于100%的数据: 1 ≤ n ≤ 1 0 7 1\leq n\leq10^7 1≤n≤107,通过计算我们大概可以得出 2 25 > 1 0 7 2^{25}>10^7 225>107,则可以直接将25遍历到1,遍历中如果 n > 2 i n>2^i n>2i,说明可以拆分,就将 2 i 2^i 2i输出并执行 n − 2 i n-2^i n−2i,不断循环。
5.代码实现
#include<iostream>
#include<cmath>
using namespace std;
int main(){
long long n;
cin>>n;
if(n%2==0){ //n是偶数
for(int i=27;i>=1;i--) //这里写27并不影响,比25大一点点都可以
{
if(n>=pow(2,i)){
//pow(x,y)是在求x的y次幂,这里一定要强转成int类型,因为pow()返回的是double类型
cout<<int(pow(2,i))<<" ";
n-=pow(2,i);
}
}
}
else{
cout<<"-1"; //n是奇数
}
return 0;
}