昨天晚上(其实是今天早上)睡觉前想着做一道水题找找自信,就找个一道1500分的题。
一开始以为不难,随便模拟就行了。
但没想到代码还挺复杂,关键是没有考虑到通过改变?
产生
的abacaba
子串的同时还不能产生其它的abacaba
子串。
例如
s
=
a
b
a
c
a
b
?
b
a
c
a
b
a
s~=~abacab?bacaba
s = abacab?bacaba 的时候就要输出“No”。
C o d e Code Code
#include <bits/stdc++.h>
#define int long long
#define sz(a) ((int)a.size())
#define all(a) a.begin(), a.end()
using namespace std;
using PII = pair<int, int>;
using i128 = __int128;
const int N = 2e5 + 10;
int n;
string s;
string model = "abacaba";
void solve() {
cin >> n >> s;
int now_exist = 0; // 现成的“abacaba”的个数
for (int i = 0; i + 6 <= sz(s) - 1; i ++) {
int l = i, r = i + 6;
int ok = 1;
for (int j = l, k = 0; j <= r; j ++, k ++) {
if (s[j] == '?' || s[j] != model[k]) {
ok = 0;
break;
}
}
if (ok) {
now_exist ++;
}
}
if (now_exist >= 2) { // 现成的model个数>=2
cout << "No\n";
} else if (now_exist == 1) {
/*
现成的model个数==1,
那么直接把所有的'?'全部换成model中不存在的字母即可
*/
for (auto &p : s) {
if (p == '?') {
p = 'd';
}
}
cout << "Yes\n";
cout << s << "\n";
} else {
for (int i = 0; i + 6 <= sz(s) - 1; i ++) {
int l = i, r = i + 6;
int ok = 1;
for (int j = l, k = 0; j <= r; j ++, k ++) {
if (s[j] != '?' && s[j] != model[k]) {
ok = 0;
break;
}
}
if (ok) {
/*
虽然这个地方能通过替换'?'出现model,
但还要保证没有其他新出现的model.
例如这种情况就不行:
s = "abacab?bacaba".
因为如果把中间的'?'换成'a'就会出现两个model
*/
string ss = s; // 复制s字符串
for (int i = l, k = 0; i <= r; i ++, k ++) {
ss[i] = model[k];
}
string sss = ss.substr(0, r);
// 如果ss字符串中model位置的左边新出现其他model
if (sss.find("abacaba") != sss.npos) {
continue;
}
sss = ss.substr(l + 1);
// 如果ss字符串中model位置的右边新出现其他model
if (sss.find("abacaba") != sss.npos) {
continue;
}
// 替换'?' + 输出
for (auto &p : ss) {
if (p == '?') {
p = 'd';
}
}
cout << "Yes\n";
cout << ss << "\n";
return;
}
}
cout << "No\n";
}
}
signed main() {
ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
int T = 1;
cin >> T; cin.get();
while (T --) solve();
return 0;
}