题目:http://acm.hdu.edu.cn/showproblem.php?pid=5414
题意:给定字符串s和t,可以在s里面选一个字符c,然后任选一个字符d(d!=c)将d插入到c的后面,问能不能将s变为t。
分析:先考虑可以插的字符(串)的情况,若在字符串"sd"的字符s后面插字符串p(|p|>=1),只要p[0]!=‘s’就行,比如p="oola",第一个o插在's'后面,第二个也插在's'后面,是可以的。那么对s和t里面的字符进行匹配,并且是t里面字符的下标尽量靠后(从后往前扫),标明t里面哪些字符是s里面固定的。再从前往后直接判断两个标记字符中间的串的第一个字符是否满足条件。特殊情况"aaa"和“aasaa”,如果后面两个a匹配的话显然不行,从前往后判断的时候顺便修改一下匹配值就行了。
代码:
#include <iostream>
#include <cstring>
#include <cstdio>
using namespace std;
const int maxn = 1e5+6;
char s1[maxn],s2[maxn];
int match[maxn];
int main()
{
int ncase,len1,len2,i,j,NO;
scanf("%d",&ncase);
while(ncase--)
{
scanf("%s%s",s1,s2);
len1=strlen(s1);
len2=strlen(s2);
if(s1[0]!=s2[0] || len1>len2)
{
printf("No\n");
continue ;
}
NO = 0;
j=len2-1;
for(i=len1-1;i>=1;i--)
{
while(j>=0 && s2[j]!=s1[i])
j--;
if(j<1)
{
NO=1;
break;
}
match[i]=j--;
}
match[0]=0;
if(NO)
{
printf("No\n");
continue ;
}
for(i=0;i<len1;i++)
{
if(i+1<len1 && match[i+1]==match[i]+1)
continue ;
if(s2[match[i]+1]==s1[i])
{
if(i+1<len1 && s1[i+1]==s2[match[i]+1])
{
match[i+1]=match[i]+1;
continue ;
}
NO=1;
break;
}
}
if(NO)
printf("No\n");
else
printf("Yes\n");
}
return 0;
}