P6661 [POI 2019] Pomniejszenie

· · 题解

P6661 [POI 2019] Pomniejszenie

POI 合集。

阴间模拟题。考虑求出使得 A, B 不同的第一个位置 p,有如下限制:

具体地,对于每一位 i,求出 s 表示在第 i 位之前有多少 A\neq B 的位置。i 合法的必要条件是 B_i \neq 0,先判掉。由于上述限制要求修改位置数量既不能太小,也不能太大,所以需要考虑当前位是否修改:

若找不到合法的 p 则无解。输出答案的过程时刻维护 k 表示还需要修改的位数:

时间复杂度线性。

#include <bits/stdc++.h>
using namespace std;

const int N = 1e5 + 5;

int n, k, p;
char s[N], t[N];
void solve() {
    scanf("%s %s %d", s + 1, t + 1, &k), n = strlen(s + 1), p = 0;
    for(int i = 1, pr = 0; i <= n; i++) {
        if(t[i] - '0') {
            if(s[i] < t[i] && pr <= k && n - i >= k - pr) p = i;
            if((t[i] > '1' || s[i] > '0') && pr + 1 <= k && n - i >= k - pr - 1) p = i;
        } pr += s[i] != t[i];
    } if(!p) return puts("-1"), void();
    for(int i = 1, out; i <= n; i++) {
        if(i < p) out = t[i];
        else if(!k) out = s[i];
        else if(i == p) out = t[i] - 1 - (s[i] + 1 == t[i] && n - i + 1 == k);
        else out = '9' - (n - i + 1 == k && s[i] == '9');
        putchar(out), k -= out != s[i];
    } cout << endl;
}
int main() {
    int T; cin >> T; while(T--) solve();
    return 0;
}