No to Palindromes!
Created by LXC on Sat Apr 29 13:27:26 2023
https://codeforces.com/problemset/problem/464/A
ranting: 1700
tag: greedy, strings
题意
给出n和p
给出一个字符串,由小写字母组成。
这个字符串是tolerable,当字符串没有长度超过1的回文子串。且字符串中每个字母的字典序都不超过p。
给出的字符串是tolerable的,求按照字典序升序下一个tolerable的串
如果没有就输出no
题解
只要任意相邻的字母不相等,且间距为1的字母不相等则这个串就是tolerable。
我们增长一个字母的字典序这样就可以让原字符串的字典序增长。
而为了保证字典序增大程度尽可能小,需要从后向前考虑找到一个字符s[x]
,并增长字符字典序,增长字典序后的s[x]
保证与s[x-1], s[x-2]
不同
如果我们找到了一个可以增长的位置x,那么其实也就找到了答案。
s[x]
之后的后缀可以从abc
中选择构造,并保证构造的字符与前两个字母不同。
代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62
| #include <bits/stdc++.h> #define SINGLE_INPUT #define ll long long #define N 500005 #define MOD 998244353 using namespace std;
void sol() { int n, p; cin >> n >> p; string s; cin >> s; if (p == 1) { cout << "NO\n"; } if (p == 2) { if (s == "a") cout << "b\n"; else if (s == "ab") cout << "ba\n"; else cout << "NO\n"; } if (p < 3) return; for (int i = n - 1; i >= 0; i--) { for (char j = s[i] + 1; j < 'a' + p; j++) { if (i - 1 >= 0 && s[i - 1] == j) continue; if (i - 2 >= 0 && s[i - 2] == j) continue; s[i] = j; for (int k = i + 1; k < n; k++) { char c = 'a'; while (k - 1 >= 0 && s[k - 1] == c || k - 2 >= 0 && s[k - 2] == c) c++; s[k] = c; } cout << s << "\n"; return; } } cout << "NO\n"; } int main() { ios::sync_with_stdio(false); cin.tie(0); cout.tie(0); #ifndef SINGLE_INPUT int t; cin >> t; while (t--) { sol(); } #else sol(); #endif return 0; }
|