解题思路:
一般来说,一个正整数可以拆分成若干个正整数的和。例如,1 = 1,10 = 1 + 2 + 3 + 4 等。
对于正整数 n 的一种特定拆分,我们称它为“优秀的”,当且仅当在这种拆 分下,n 被分解为了若干个不同的 2 的正整数次幂。注意,一个数 x 能被表 示成 2 的正整数次幂,当且仅当 x 能通过正整数个 2 相乘在一起得到。
例如,10 = 8 + 2 = 23 + 21 是一个优秀的拆分。但是,7 = 4 + 2 + 1 = 22 + 21 + 20 就不是一个优秀的拆分,因为 1 不是 2 的正整数次幂。
现在,给定正整数 n,你需要判断这个数的所有拆分中,是否存在优秀的 拆分。若存在,请你给出具体的拆分方案。
注意事项:
需要从大到小输出 这个拆分中的每一个数
参考代码:
#include<iostream>
using namespace std;
#include<cmath>
int judge(int n)//判断是否为2的幂次方
{
int x;
while (n)
{
x = n % 2;//余数
n = n / 2;//商
if (x == 1) //若余数为1,则不是2的幂次方
return 0;
if (x == 0 && n == 1)//若余数为0 时且商为1时,是2的幂次方(可自己举例验证)
return 1;
}
}
//judge判断还可以采用一种更高级的方法,只需一行代码,原理如下:
//把一个数n拆成二进制看待处理的,如果 n 是 2 的幂次方的话,那么 n 的二进制数的最高位是 1,后面的都是 0。如果我们把它减 1,则会导致最高位变成 0,其余全部变成 1。然后我们把 n 和 (n - 1)进行与操作,结果就会是 0。例如:16=1 0000,(1 0000 & 0 1111)=0。代码如下:
//int judge(int n)
//{ return (n&(n-1))==0; } n&(n-1)的值为1,表示n不是2的幂次方,1!=0,此时返回0;反之,n&(n-1)的值为0,表明n是2的幂次方,0==0,成立,此时返回1
int fact(int n)//从大到小输出2的幂次方
{
int i = 1;
if (judge(n))//n本身就是2的幂次方,则它是"优秀的"
{
cout << n << " ";
return 0;
}
for (i = 1; pow(2, i) < n; i++);//此处循环没有循环内容,是为了找出小于n的最大2的幂次方
int a = pow(2, i - 1);
cout << a<<" ";
if (judge(n - pow(2,i)))//判断剩下的是不是 2 的正整数次幂
{
cout << n - pow(2, i-1)<<" ";
return 0;
}
else//不是的话,递归寻找,通俗讲就是每次都减去一个小于n的最大2的幂次方,在差里寻找下一个小于差的最大2的幂次方
fact(n - a);
}
int main()
{
int n;
cin >> n;
if (n % 2 == 1)//奇数一定不是"优秀的"
cout << "-1" << endl;
else
fact(n);
return 0;
}
0.0分
4 人评分
WU-复数求和 (C++代码)浏览:2119 |
本人酷爱递归实现很多问题,这里也是浏览:632 |
WU-格式化数据输出 (C++代码)浏览:1312 |
C语言程序设计教程(第三版)课后习题1.5 (C语言代码)浏览:512 |
C语言程序设计教程(第三版)课后习题11.1 (C语言代码)浏览:651 |
Hello, world! (C语言代码)浏览:766 |
2003年秋浙江省计算机等级考试二级C 编程题(2) (C语言代码)浏览:654 |
理财计划 (C语言代码)浏览:494 |
C语言程序设计教程(第三版)课后习题8.9 (C语言代码)浏览:576 |
小O的图案 (C语言代码)浏览:979 |
一个人的巴黎 2022-02-17 08:40:05 |
优秀的你!!!