题目描述
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
");
else printf("NO
");
}
}