关于 ABC416 G
  • 板块学术版
  • 楼主Nazq
  • 当前回复0
  • 已保存回复0
  • 发布时间2025/7/27 10:48
  • 上次更新2025/7/27 11:31:30
查看原帖
关于 ABC416 G
1051166
Nazq楼主2025/7/27 10:48

看到一种解法,就跑 10 次往前插最优的,然后最前面就只需要放最小的。正确性如何证明?

    int n, k;
    cin >> n >> k;
    vector<string> v(n);

    for (int i = 0; i < n; i++) cin >> v[i];
    
    string mn = *min_element(v.begin(), v.end());
    if (k == 1) {
        cout << mn;
        return 0;
    }

    string ans, temp;
    auto cmp = [&](string a, string b) -> bool {
        string a1 = a + ans;
        string b1 = b + ans;
        return a1 <= b1;
    };

    for (int i = 0; i < min(10ll, k); i++) {
        sort(v.begin(), v.begin() + n, cmp);
        ans = v[0] + ans;
        temp = v[0];
    }

    for (int i = 0; i < k - 10; i++) cout << temp;
    cout << ans;

我的理解是,官解证明了答案一定是 smins_{min} 无限复制的前缀,于是答案最终由 smins_{min} 复制若干遍。最后选出一些串构成 smins_{min} 的前缀。因为长度不超过 1010,所以跑 1010 遍一定可以找到前缀。

但是不理解倒着跑为啥一定对?

2025/7/27 10:48
加载中...