HDU 5414 CRB and String (2015 Multi-University Training Contest 10 2015多校联合)

CRB and String

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 0    Accepted Submission(s): 0


Problem Description
CRB has two strings  s  and  t .
In each step, CRB can select arbitrary character  c  of  s  and insert any character  d  ( d  c ) just after it.
CRB wants to convert  s  to  t . But is it possible?
 

Input
There are multiple test cases. The first line of input contains an integer  T , indicating the number of test cases. For each test case there are two strings  s  and  t , one per line.
1 ≤  T  ≤  105
1 ≤  |s|  ≤  |t|  ≤  105
All strings consist only of lowercase English letters.
The size of each input file will be less than 5MB.
 

Output
For each test case, output "Yes" if CRB can convert s to t, otherwise output "No".
 

Sample Input
  
  
4 a b cat cats do do apple aapple
 

Sample Output
  
  
No Yes Yes No

题目链接: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<m(题目中有描述n不大于m),我们的a串只要满足如下两个条件即可:

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<stdio.h>
#include<string.h>
#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<m;i++)
            {
                if(a[i]!=b[i])
                {
                    flag=2;
                    break;
                }
                else
                    continue;
            }
        }
        else
        {
            for(j=1;j<m;j++)
            {
                if(b[j]==b[j-1])
                    continue;
                else
                    break;
            }
            for(i=0;i<j;i++)
            {
                if(a[i]!=b[i])
                {
                    flag=2;
                    can=0;
                    break;
                }
            }
            if(can==1)
            {
                for(i=j;i<n;i++)
                {
                    for(k=j-1;k<m;k++)
                    {
                        if(a[i]==b[k])
                        {
                            count++;
                            break;
                        }
                    }
                    if(count==0)
                        break;
                }
                if(count==n-j)
                    flag=1;
                else
                    flag=0;
            }
        }
        if(flag==1)
            printf("Yes\n");
        else
            printf("No\n");
    }
    return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值