Slavic's Exam 的题解
记住只在没有思路时使用题解,不要从它复制粘贴代码。请尊重题目和题解的作者。
在解题之前提交题解的代码会导致封禁。
在解题之前提交题解的代码会导致封禁。
作者:
概述
本题要求将字符串 中的每个
? 替换为小写字母,使目标串 成为
的子序列,并输出任意可行结果。核心解法是贪心双指针匹配,遇到
? 优先匹配当前需要的 字符,剩余
? 补 a。
分析
核心观察
若当前字符是 ?,将它替换为 当前待匹配字符一定不劣于替换为其他字符,因为它能推进匹配进度且不会影响后续字符的可匹配性。
思路
维护指针 遍历
,指针
指向
中下一个需要匹配的位置。对于每个位置
:
- 若
是
?,则将其设为(若
尚未越界),并将
加
;若
已经等于
,则任意填
a。 - 若
不是
?,且且
,则匹配成功,
加
。
- 其他情况不匹配,继续向后扫描。
该贪心策略的正确性基于:? 作为万能字符,越早用于匹配 的当前字符,就能为后续字符留下更多机会;若某个
? 不匹配当前字符而等后续可能匹配,反而可能因后续非 ? 字符错过匹配,因此当前匹配是最优的。
遍历结束后,若 ,说明全部匹配成功,将所有剩余的
? 替换为 a(样例中未提及,但参考代码和逻辑如此),输出 YES 和结果;否则输出 NO。
具体示例
以样例第一组 s = "?????",t = "xbx" 为例:
- 初始
,遍历所有
?,依次将前三个?设为x, b, x,变为
,剩余两个
?填a,得到xabax,匹配成功。
以样例第四组 s = "ab??e",t = "dac" 为例:
- 遍历
:
a不匹配d,b不匹配d,遇到第一个?设为d,;第二个
?设为a,;
e不匹配c,最终,输出
NO。
算法步骤
- 对每个测试用例,读入字符串
和
。
- 初始化匹配指针
idx = 0。 - 遍历
的每个字符
ch:- 若
ch为?:- 若
idx小于t的长度,则将当前字符设为t[idx],并将idx加;
- 否则,将当前字符设为
a。
- 若
- 否则(
ch不是?):- 若
idx小于t的长度且ch == t[idx],则将idx加。
- 若
- 若
- 遍历结束后,若
idx == t.length(),则输出YES和修改后的;否则输出
NO。
复杂度分析
- 时间:
,每个字符处理常数次,所有测试用例总长度
。
- 空间:
额外空间(不计输入输出)。
实现注意事项
- 在判断非
?字符是否匹配时,必须确保idx < t.size(),否则访问t[idx]越界;参考代码中缺少该判断,实现时需补全。 - 若已匹配完所有
,后续
?可统一填a,其他字符保持不变。 - 输出时,
YES和NO大小写均可,但本题解统一输出大写。 - 所有测试用例的
之和不超过
,使用
string类型直接存储和修改即可。
源代码
#include <bits/stdc++.h>
using namespace std;
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
int T;
cin >> T;
while (T--) {
string s, t;
cin >> s >> t;
int idx = 0;
int n = (int)s.size(), m = (int)t.size();
for (int i = 0; i < n; ++i) {
if (s[i] == '?') {
if (idx < m) {
s[i] = t[idx];
++idx;
} else {
s[i] = 'a';
}
} else {
if (idx < m && s[i] == t[idx]) {
++idx;
}
}
}
if (idx == m) {
cout << "YES\n" << s << '\n';
} else {
cout << "NO\n";
}
}
return 0;
}
import sys
def solve():
input_data = sys.stdin.read().strip().split()
T = int(input_data[0])
pos = 1
out_lines = []
for _ in range(T):
s = list(input_data[pos]); pos += 1
t = input_data[pos]; pos += 1
idx = 0
m = len(t)
for i in range(len(s)):
if s[i] == '?':
if idx < m:
s[i] = t[idx]
idx += 1
else:
s[i] = 'a'
else:
if idx < m and s[i] == t[idx]:
idx += 1
if idx == m:
out_lines.append("YES")
out_lines.append("".join(s))
else:
out_lines.append("NO")
sys.stdout.write("\n".join(out_lines))
if __name__ == "__main__":
solve()
评论