题解 P3333 【[ZJOI2013]丽洁体】
题意:给定字符串序列
首先,由于要得到的串开头和结尾要是
于是现在我们将问题变成了如何在开头和结尾之间这一段找一个跨度最小的包含
按照常规思路我们应该考虑
然后我们就发现
仔细观察一下数据范围,发现有一句“所有单词长度不超过
有由于“单词长度不超过 string 暴力匹配)
于是这题就彻底沦为了普及组的序列暴力匹配练习题。。。
#include<cstdio>
#include<string>
const int N=50010;
int n,a,b,c,ans,mn;
std::string sn[N],sa[N],sb[N],sc[N];
void read(int &n,std::string sn[])
{
char ch;
do ch=getchar();while(ch<=32);
for(n=1;;n++)
{
do sn[n]+=ch,ch=getchar(); while(ch>32);
while(ch<=32){if(ch=='\n'||ch==EOF)break;ch=getchar();}
if(ch=='\n'||ch==EOF)break;//读到换行符就停止
}
}
int main()
{
int i,j;
read(n,sn);read(a,sa);read(b,sb);read(c,sc);//读入
for(i=j=1;j<=a;i++)
if(sn[i]==sa[j])++j;//暴力匹配
ans+=i-1-a;int l=i;
for(i=n,j=c;j>=1;i--)
if(sn[i]==sc[j])--j;//暴力匹配
ans+=n-i-c;int r=i;
for(;l<=r;l++)
if(sn[l]==sb[1])
{
for(i=l,j=1;j<=b;i++)
if(sn[i]==sb[j])++j;//暴力匹配
if(i-1<=r&&mn>i-l-b)mn=i-l-b;
}
ans+=mn;
printf("%d\n",ans);//完
return 0;
}
ps:各位不要再尝试抄题解了,也建议管理员查一下这题大部分AC代码都一模一样的现象。