洛谷P7071 [CSP-J2020] 优秀的拆分题解

1.题目链接

P7071[CSP-J2020]优秀的拆分

2.题意描述

输入一个整数n,判断此数是否能被分解为若干个不同的2的正整数次幂,若能够则需要从大到小输出拆分中的每个数,若不能则输出-1。
注:上方被加粗的两个词语
(1)不同:拆分中的每个数字不可以相同,即2的次幂也不可相同
(2)正整数:大于0的整数,即拆分中不得出现1( 2 0 2^0 20)

3.样例解读

洛谷P7071 [CSP-J2020] 优秀的拆分题解_第1张图片

  • 样例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 1n107,通过计算我们大概可以得出 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 n2i,不断循环。

5.代码实现

#include
#include
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;
} 

你可能感兴趣的:(算法,c++)