4103 All in All
Time Limit: 1000/1000MS (C++/Others) Memory Limit: 65536/65536KB (C++/Others)
Total Submissions: 335 Accepted Submissions: 177
Problem Description
给定两个字符串s和t,判断s是否是t的子序列。即从t中删除一些字符,将剩余的字符连接起来,即可获得s。
Input
输入文件包括多组测试数据,每组测试数据占一行,包括两个由ASCII码组成的字符串s和t,它们的长度都不超过100000。
Output
对于每个测试数据输出一行,如果s是t的子序列,则输出“Yes”,否则输出“No”。
Sample Input
sequence subsequence
person compression
VERDI vivaVittorioEmanueleReDiItalia
caseDoesMatter CaseDoesMatter
Sample Output
Yes
No
Yes
No
思路
读懂题 :
看题要求及例子,我们最终可以总结出:字符串s可以按顺序拆成单个字符序列,若在字符串t中能找到按顺序排列的拆开的字符串t,也可以算“字符串t包含字符串s”。
解题方法:
这里,我们把第一个字符串s中的每一个字符看作标有对应字符的签子,把第二个字符串t的每一个字符看作标有字符的桶,这个桶只能放入和这个桶上字符相同的签子。然后我们可以从右边开始遍历这个桶。
(1)拿出字符串s中最右边的一个签子,然后开始找与其对应的桶;
(2)若找到了,则把签子放进去,即把count - - ;
(重复上面两步,如果最后能把字符串s中的签子都放进去,则说明证明“字符串t包含字符串s”;若没有放完,则字符串t不包含字符串s)
这里给出一个例子(字非常丑…):
代码如下:
#include <iostream>
#include <cstring>
using namespace std;
int main() {
char s1[100010],s2[100010];
int i,j,count;
while(~scanf("%s %s\n",s1,s2))
{
count = strlen(s1);//count为签子总数
for(i = strlen(s2)-1;i>=0;i--)
{
for(j=count-1;j>=0;j--)
{
if(s1[j]==s2[i])
{
count--;//签子一旦找到对应的桶 ,就把签子放进去
break; //开始找下一个签子对应的桶
}
}
}
if(count!=0)//如果签子没有放完,则说明字符串t不包含字符串s
cout<<"No"<<endl;
else
cout<<"Yes"<<endl; //如果签子放完了,则说明字符串t包含字符串s
}
return 0;
}