[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次幂类型,有点难度,只需要注意特舒情况即可~

求个置顶~

posted @ 2026-10-01 18:50  Spencer20262026  阅读(8)  评论(0)    收藏  举报