[CSP-J2020A] 优秀的拆分 (Excellent Split) 题解
这期是正经题解,不整活了,已同步上传至题解
写完才发现题解bot已经写了,%%%
题目:
本文中仅使用cin,cout输入输出格式,应该没人看不懂吧 绝对不是因为我不会
题目大意
对于N的一个特殊拆分,若N能分解为形如\(2^a + 2^b +2^c + ... +2^n\)(\(a!=b!=...!=n!=0\)),称这个正整数N的拆分为“优秀的”
思路:从最大\(2^n\)向下便利搜索即可
特殊情况
1.通过观察题目,不难发现,若N为奇数,那么N一定不可能拆出“优秀的拆分”(在2的n次方中,有且仅有\(2^0\)为奇数,而题目中要求仅能使用“2的正整数次方”)直接特判即可
2 \(2^n\)情况,下面代码中直接包含这种了,但我之前写暴力代码的时候\(2^n\)会出现少输出的情况,需要注意,可以写特判
Code:
#include<bits/stdc++.h>
using namespace std;
#define int long long // 把代码中所有int替换成long long,防止大数溢出
signed main() {
int n;
cin >> n; // 输入目标数字n
// 判定:如果n是奇数,直接输出-1
if (n % 2 == 1)
{
cout << "-1" << endl;
return 0;
}
// 找到 ≤ n 的最大的2的幂次
int mx = 1;
while (mx * 2 <= n)
{
mx *= 2; // mx不断乘2,直到再乘2就超过n
}
bool first = true; // 标记是否是第一个输出的数,用来控制空格,避免开头多余空格
// 从最大的2的幂向下遍历,依次拆分n
while (n > 0 && mx >= 2)
{
// 如果当前剩余n大于等于这个2的幂,可以选用这个数
if (n >= mx)
{
if (!first){
cout << " "; // 不是第一个数字,先输出空格分隔
}
cout << mx; // 输出当前2的幂
n -= mx; // 剩余数值减去已经选用的数
first = false; // 已经输出过数字,后续需要加空格
}
mx /= 2; // 换到下一个更小的2的幂(除以2)
}
return 0;
}
总结:
十分常见的二的n次幂类型,有点难度,只需要注意特舒情况即可~
求个置顶~
浙公网安备 33010602011771号