P6661 [POI 2019] Pomniejszenie
P6661 [POI 2019] Pomniejszenie
POI 合集。
阴间模拟题。考虑求出使得
- 需要修改的位置数量不能超过
k 。 - 没有考虑到的位置数量不能小于还需要修改的位数。
具体地,对于每一位
- 若
A_i < B_i ,说明可以不修改。此时若s \leq k 且n - i \geq k - s 则i 合法。 - 若
B_i > 1 或A_i > 0 ,说明可以 强制 修改(因为当A_i = 0, B_i = 1 时不能修改)。此时若s + 1\leq k 且n - i \geq k - s - 1 则合法。
若找不到合法的
- 若当前位
i 小于p ,输出B_i 。 - 若当前位
i 等于p ,此时当n - i + 1 = k 且A_i + 1 = B_i 时输出B_i - 2 ,否则输出B_i - 1 ,前者因为这一位必须修改(否则将导致剩余位数小于要修改位数,不合法)。 - 若当前位
i 大于p ,此时当n - i + 1 = k 且A_i = 9 时输出8 ,否则输出9 。 - 注意点:若输出的数码与
A_i 不同,则令k 自减1 。 - 注意点:任何时刻若
k = 0 ,则输出A_i 。
时间复杂度线性。
#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;
}