UPC-6491 Daydream(KMP子串计数&特判)

题目描述
You are given a string S consisting of lowercase English letters. Another string T is initially empty. Determine whether it is possible to obtain S=T by performing the following operation an arbitrary number of times:
Append one of the following at the end of T: dream, dreamer, erase and eraser.

Constraints
1≤|S|≤105
S consists of lowercase English letters.
输入
The input is given from Standard Input in the following format:
S
输出
If it is possible to obtain S=T, print YES. Otherwise, print NO.
样例输入
erasedream
样例输出
YES
提示
Append erase and dream at the end of T in this order, to obtain S=T.

题意:给四个串,dream, dreamer, erase , eraser.再给一个串S,问是否能用给出的几个串T组成一个串S。

直接对串S查询每个单词出现的次数,然后用次数乘串长度求和,看是否等于S串长。
注意一个特判,当dream和erase两个单词相邻时会判定为dreamer和ase两个单词,此时应该减去这样的次数计数。

#include<bits/stdc++.h>
#define LL long long
using namespace std;
const int maxn=1e5+10;
int n;
char a[maxn];
void kmp_pre(char x[],int m,int next[])
{
    int i,j;
    j=next[0]=-1;
    i=0;
    while(i<m)
    {
        while(j!=-1&&x[i]!=x[j])j=next[j];
        next[++i]=++j;
    }
}
int kmp_count(char x[],int m,char y[],int n)
{
    int ans=0;
    int i=0,j=0,next[maxn];
    kmp_pre(x,m,next);
    while(i<n)
    {
        while(j!=-1&&x[j]!=y[i])j=next[j];
        i++;j++;
        if(j>=m)
        {
            ans++;
            j=0;
        }
    }
    return ans;
}
int kmp_countdrmr(char x[],int m,char y[],int n)
{
    int ans=0;
    int i=0,j=0,next[maxn];
    kmp_pre(x,m,next);
    while(i<n)
    {
        while(j!=-1&&x[j]!=y[i])j=next[j];
        i++;j++;
        if(j>=m)
        {
            ans++;
            if(y[i]=='a'&&y[i+1]=='s'&&y[i+2]=='e')ans--;
            j=0;
        }
    }
    return ans;
}
char dream[]="dream";
char dreamer[]="dreamer";
char erase[]="erase";
char eraser[]="eraser";
int lendrm=strlen(dream);
int lendrmr=strlen(dreamer);
int lenera=strlen(erase);
int lenerar=strlen(eraser);
int main()
{
    while(scanf("%s",a)!=EOF)
    {
        int len=strlen(a);
        int drm=kmp_count(dream,lendrm,a,len);
        int drmr=kmp_countdrmr(dreamer,lendrmr,a,len);
        int era=kmp_count(erase,lenera,a,len);
        int erar=kmp_count(eraser,lenerar,a,len);
        drm-=drmr;
        era-=erar;
        if(drm*lendrm+drmr*lendrmr+era*lenera+erar*lenerar==len)printf("YES\n");
        else printf("NO\n");
    }
}

猜你喜欢

转载自blog.csdn.net/kuronekonano/article/details/80525844
UPC
今日推荐