洛谷传送门:P7071 [CSP-J2020] 优秀的拆分 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)
写在最前面
首先,如果你很很熟悉十进制传二进制的代码,那么这道题对你而言就十分简单。但也不是说不会十进制传二进制,这道题我就做不来。没想到算法怎么办?那肯定是暴力+剪枝
能AC的暴力代码(能到O(1)的时间复杂度 !)
首先明确一点,就是奇数肯定不是优秀的拆分。因为奇数绝对会拆出来2的0次方,那么我们看到奇数就return 0;
先看数据范围
我们就可以很开心的直接生成一个等比数列,从2的一次方列举到2的30次方,然后从2的30次方到这循环到2的1次方,用输入的n来判断是不是比当前遍历到的值大,如果大,就输出当前的值,并且用n减掉。不然就一直循环直到遍历完整个等比数列。
#include<bits/stdc++.h>
using namespace std;
int n;
long long a[30];
int main(){
cin>>n;
if(n%2==1){
cout<<"-1";
return 0;
}
a[1]=1;
for(int i=2;i<=26;i++){
a[i]=a[i-1]*2;
}
for(int i=26;i>=2;i--){
if(n>=a[i]){
n-=a[i];
cout<<a[i]<<' ';
}
}
return 0;
}
简单易懂
用十进制传二进制的方法
你可以发现他的本质其实就是转成二进制,然后从大到小输出每一位
直接上代码
#include <bits/stdc++.h>
using namespace std;
int n;
int ans[50];
int main()
{
scanf("%d",&n);
if (n%2!=0){
printf("%d",-1);
return 0;
}
n/=2;
int i=0;
while (n>0){
i++;
ans[i]=n%2*pow(2,i);
n/=2;
}
for (int j=i;j>=1;j--){
if (ans[j]!=0){
printf("%d ",ans[j]);
}
}
return 0;
}
原代码链接:https://blog.csdn.net/qq_36230375/article/details/131555827