题目链接:
http://acm.hdu.edu.cn/showproblem.php?pid=5414
解题思路:
官方题解:
Let us assume that s can be converted into t.
Obviously, s must be subsequence of t. We can check this in linear time.
And, we also consider state of the first character.
If the first k characters of t are equal to c, the first k characters of s must be also equal to c.
It can be easily proved that s can be converted into t when the above two conditions are satisfied.
Time complexity:O(∣s∣+∣t∣)
题目大意:
输入两个字符串s和t,你可以选择字符串s中的任意一个字母c,在这个字母的后面加任意一个不是x的字母。最后使s变成t。如果能变成t输出Yes,否则
输出No。
算法思想:
1、t开头的几个相同的字符的字母必须能和s对应。
2、字符串t包含字符串s,也就是说s出现的字母在t里必须都有。否则aab、aaaaa这样的就不行。你无论如何也添加不出来。
唯一比较难想的是诸如ale如果添加到apple,似乎需要往a后面加2个p才能得到,但其实可以通过先加一个p,然后再向a后加1个p,就可以成功避开题
目c!=d的限制.。。
其实仔细一分析,成功转化只包含两种情况。
第一种因为要求插入的新字符和它前面的字符c不同,如果t前面中有x个连续的c,那么在s中也必须有x个连续的c;
第二种是s必须是t的一个不连续子串。
AC代码:
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
const int N = 100005;
char s[N],t[N];
int solve(){
int i,j;
int l1 = strlen(s);
int l2 = strlen(t);
for(i = 1; i < l2; i++)
if(t[i] != t[0])
break;//找到t串的第一个不连续的位置
for(j = 0; j < i; j++)//看s的前i个子串是否连续
if(s[j] != t[0])
return 0;
for(; j<l1;){
for(; i<l2; i++){//找到下一个和s相等的地方
if(t[i] == s[j])
break;
}
if(i == l2)
return 0;//如果t找完了还没跳出证明s不是t的子串
i++;
j++;
}
return 1;
}
int main(){
int T;
scanf("%d",&T);
while(T--){
scanf("%s%s",s,t);
if(solve())
printf("Yes\n");
else
printf("No\n");
}
return 0;
}