题目链接:HDU5414 CRB and String
题意就是每组测试数据输入两个字符串a和b,你可以选择字符串a中的任意一个字母x,在这个字母的后面加任意一个不是x的字母(看不懂看下面举例子~)。最后使a变成b。如果能变成b输出Yes,否则输出No。
比如:字符串a是abc,b是abefchi。那么你可以把a这样加:abc→abec→abefc→abefch→abefchi,我们就可以把a变成b,输出yes。
如果字符串a是apple,b是aapple。这时候要注意:你不能在字符串a中的字母a后面再加一个a。也就是说把apple→aapple是不行的。因为题目说,不可以加和选择的字母相同的字母。
哦对了补充一点,不选择也是可以的,也就是说字符串a是abcde,字符串b是abcde,输出是yes。
那么我们来分析一下:
首先,用strlen分别求a和b的长度,记为n和m。
如果n==m,那么我们只要加一个for循环从0到n,逐个判断是否a[i]==b[i]即可。
如果不等于。也就是n
1、字符串b包含字符串a,也就是说a出现的字母在b里必须都有。否则aaab、aaacc这样的就不行。你无论如何添加不出来。
2、b开头的几个相同的字符的字母必须能和a对应。下面来解释一下:
因为向a中添加字母,必须是先选择一个字母,然后在其后面添加,所以你无法向字符串a的前面添加字母,只能是中间任意位置和后面。这说明什么呢?(首先我们可以用顺序结构,也就是for循环搞定- -不用再考虑是不是中间的部分子串的问题了=。= ) 好了,我们来把字符串b分成两部分。第一部分是串b从头开始出现的相同的字母,第二部分是余下的。比如aaaabcdefg
下面稍微解释一下:
例如b串是baaa,分成两块是baaa 那么我们的子串a只要第一个字母b匹配上了,并且满足上面的条件1,就总是能变成b。因为即使b串中间有3个连续的a,但是我们总是可以在子串a中字母b的后面添加a。比如此时串a是b,那么我们只要通过向b后面添加a,添加3次就ok了。过程:b→ba→baa→baaa接下来的问题就是如果串b是aaaabcdefg这样该怎么处理呢?
首先对于第一部分,我们用for循环从头找一共有几个相同的字母出现,用j记录。然后a串同样用for从0到j循环,挨个去看是不是都和a对应相同。
如果第一部分相同了,我们只要去判断是否满足第一个条件即可,即判断第二部分的字母是不是都被母串b包含。只要都包含的话,我们是一定可以最后把a变成b的。(在这里你可以把第一部分这个整体看做是一个字母)
AC代码:
Problem : 1009 ( CRB and String ) Judge Status :
RunId : 7582 Language : C Author :
Code Render Status : Rendered By HDOJ C Code Render Version 0.01 Beta
#include
#include
#define N 100010
#define M 100010
char a[N],b[M];
int next[M];
int n,m;
int main()
{
int T,flag,i,j,k,count,can;
scanf("%d",&T);
while(T--)
{
can=1;
flag=1;
count=0;
scanf("%s",a);
scanf("%s",b);
n=strlen(a);
m=strlen(b);
if(n==m)
{
for(i=0;i