1 条题解

  • 0
    @ 2026-10-31 17:58:16

    思路

    这是一道构造题:每个位置都必须按顺序输出一次 2 或 3,且要求最后 A、B 两个集合中状态为 11 的元素个数相等。

    令 K=n−kK=n-k,按位置固定输出:

    • 前 KK 个位置输出 2(加入集合 A 并翻转该位);
    • 后 kk 个位置输出 3(加入集合 B 不翻转)。

    证明它对任意翻转方案都成立。 记系统在前 KK 个位置中翻转了 yy 个(系统总共恰好翻转 kk 个位置):

    • 前 KK 个位置原本都是 11。被系统翻过的 yy 个变成 00,其余 K−yK-y 个仍是 11。我们对这些位置执行 2,即全部翻转一次再放入 A:原来的 yy 个 00 变回 11,剩下的 K−yK-y 个 11 变成 00。所以 A 中状态为 11 的元素有 yy 个。
    • 后 kk 个位置中被系统翻过的有 k−yk-y 个,剩下 yy 个没被翻、状态仍为 11。我们对这些位置执行 3,放入 B 且不翻转。所以 B 中状态为 11 的元素也有 yy 个。

    两个集合中状态为 11 的元素数恒等于 yy,条件对任意翻转方案都成立,因此永远不需要输出 −1-1。

    边界: k=0k=0 时全部输出 2(A 中为 11 的个数仍是 yy,B 为空、为 00,此时 y=0y=0);k=nk=n 时全部输出 3,两种构造同样成立。

    直接按位置输出即可。

    复杂度: 时间 O(n)O(n),空间 O(1)O(1)(除输出外不额外存储)。

    代码

    #include <bits/stdc++.h>
    #define endl '\n'
    using namespace std;
    using i64 = long long;
    
    void solve() {
        int n,k,i;cin>>n>>k;
        // 前 n-k 个位置选 "2":加入集合 A 并翻转
        for(i=1;i<=n-k;i++){
            cout<<2;
        }
        // 后 k 个位置选 "3":加入集合 B 且不翻转
        for(;i<=n;i++){
            cout<<3;                     // 按位置连续输出,不加空格
        }
    
    }
    
    signed main() {
        ios::sync_with_stdio(0);
        cin.tie(0);
    
        int _ = 1;                       // 本题只有单组数据
        while (_--) {
            solve();
        }
        return 0;
    }
    
    • 1

    信息

    ID
    22
    时间
    1000ms
    内存
    256MiB
    难度
    5
    标签
    递交数
    1
    已通过
    1
    上传者