正在载入在线练习界面,本页内容可直接阅读…
AK CSP › CSP-S 2019 第一轮真题 › 第29题
CSP-S 2019 第一轮 第29题:当 t 是 s 的子序列时,输出一定不为 0
题目
$t$ 是 $s$ 的子序列的意思是:从 $s$ 中删去若干个字符,可以得到 $t$;特别的,如果 $s=t$,那么 $t$ 也是 $s$ 的子序列;空串是任何串的子序列。例如:$\texttt{acd}$ 是 $\texttt{abcde}$ 的子序列,$\texttt{acd}$ 是 $\texttt{acd}$ 的子序列,但 $\texttt{adc}$ 不是 $\texttt{abcde}$ 的子序列。
$s[x..y]$ 表示 $s[x] \cdots s[y]$ 共 $y-x+1$ 个字符构成的字符串,若 $x>y$ 则 $s[x..y]$ 是空串。$t[x..y]$ 同理。
#include <iostream>
#include <string>
using namespace std;
const int max1 = 202;
string s, t;
int pre[max1], suf[max1];
int main() {
cin >> s >> t;
int slen = s.length(), tlen = t.length();
for (int i = 0, j = 0; i < slen; ++i) {
if (j < tlen && s[i] == t[j]) ++j;
pre[i] = j; // t[0..j-1] 是 s[0..i] 的子序列
}
for (int i = slen - 1 , j = tlen - 1; i >= 0; --i) {
if(j >= 0 && s[i] == t [j]) --j;
suf[i]= j; // t[j+1..tlen-1] 是 s[i..slen-1] 的子序列
}
suf[slen] = tlen -1;
int ans = 0;
for (int i = 0, j = 0, tmp = 0; i <= slen; ++i){
while(j <= slen && tmp >= suf[j] + 1) ++j;
ans = max(ans, j - i - 1);
tmp = pre[i];
}
cout << ans << endl;
return 0;
}
提示:
- $t[0\dots pre[i]-1]$ 是 $s[0\dots i]$ 的子序列;
- $t[suf[i]+1\dots tlen-1]$ 是 $ s[i\dots slen-1]$ 的子序列。本小题
(2分)当 $t$ 是 $s$ 的子序列时,输出一定不为 $0$。()
选项
- T. 正确
- F. 错误
答案
F
题解
选 F(错误)。只要找出一个“$t$ 是 $s$ 的子序列,但输出为 $0$”的反例即可。
例如输入: ``text a a ` 此时 $s=t$,所以 $t$ 是 $s$ 的子序列。前两个循环得到: `text pre[0] = 1 suf[0] = -1 suf[1] = 0 ``
再看最后一个循环:
i | 进入循环时 tmp | while 结束后的 j | j-i-1 |
|---|---|---|---|
| 0 | 0 | 1 | 0 |
| 1 | 1 | 2 | 0 |
因此 ans 始终为 0,最终输出 0,原命题错误。
关键是:子序列允许两个字符串相等,并不保证还能删除字符。
真题版权归 CCF 所有,本站仅用于非商业教学用途。页面加载后可直接在线作答,作答记录保存在本浏览器或账号中。 京ICP备2026056990号-1
京公网安备11010502062986号