题意
给定两个字符串
S
,
T
S,T
S,T ,它们仅由小写字母和字符 ?
组成,其中 ?
部分代表该位置可以被替换成任意的小写字母。
请你设计程序,对于所有的 x = 0 , 1 , 2 , … , ∣ T ∣ x=0,1,2,\dots,|T| x=0,1,2,…,∣T∣,判断是否存在满足以下要求的方案:
截取 S S S 的前 x x x 位与后 ∣ T ∣ − x |T|-x ∣T∣−x 位组成新的字符串 P P P ,字符串 P P P 与 T T T 相等。
思路
这道题我们可以先使用一个字符串
X
X
X 表示后
∣
T
∣
|T|
∣T∣ 位的字符串,接着遍历
X
X
X 和
T
T
T 看看是否符合,不符合的话我们就记录一下并且将
c
n
t
cnt
cnt 加一,
c
n
t
cnt
cnt 表示当前字符串
X
X
X 与字符串
T
T
T 不相等的位的个数。如果
c
n
t
cnt
cnt 为零,则输出 Yes
,否则输出 No
。
接着我们看一下下面这个样例:
atcoder
?????
我们的每一次组出来的应是:
coder
aoder
atder
atcer
atcor
atcod
不难发现,我们更改的第
i
i
i 次只是
X
i
X_i
Xi。我们可以继续用回原本的
c
n
t
cnt
cnt,要是当前
X
i
X_i
Xi 更改后与
T
i
T_i
Ti 符合了并且原本是不符合的就讲
c
n
t
cnt
cnt 减一;要是当前
X
i
X_i
Xi 更改后与
T
i
T_i
Ti 不符合了并且原本是符合的就讲
c
n
t
cnt
cnt 加一。如果
c
n
t
cnt
cnt 为零,则输出 Yes
,否则输出 No
。
代码
#include <bits/stdc++.h>
#define int long long
using namespace std;
string s, t, x;
int bj[300005], cnt;
signed main() {
cin >> s >> t;
x = s.substr(s.size() - t.size(), t.size());//截取后面|t|位
for (int i = 0; i < x.size(); i++)
if (x[i] != '?' && t[i] != '?' && x[i] != t[i])//符合
bj[i] = 1, cnt++;//记录
printf((cnt == 0) ? "Yes\n" : "No\n");//判断
for (int i = 0; i < t.size(); i++) {
x[i] = s[i];
if (bj[i] == 1 && (x[i] == t[i] || x[i] == '?' || t[i] == '?'))
cnt--;
if (x[i] != t[i] && x[i] != '?' && t[i] != '?' && bj[i] == 0)
cnt++;
printf((cnt == 0) ? "Yes\n" : "No\n");//判断
}
return 0;
}