数据结构实验之串三:KMP应用
Time Limit: 1000ms Memory limit: 65536K 有疑问?点这里^_^
题目描述
有n个小朋友,每个小朋友手里有一些糖块,现在这些小朋友排成一排,编号是由1到n。现在给出m个数,能不能唯一的确定一对值l和r(l <= r),使得这m个数刚好是第l个小朋友到第r个小朋友手里的糖块数?
输入
首先输入一个整数n,代表有n个小朋友。(0
输出
如果能唯一的确定一对l,r的值,那么输出这两个值,否则输出-1
示例输入
5 1 2 3 4 5 3 2 3 4
示例输出
2 4
提示
来源
windream
示例程序
#include<bits/stdc++.h>
using namespace std;
int next[1000000];
int get_next(char s[])
{
int len=strlen(s);
int i=0,j=-1;
next[0]=-1;
while(i<len) //i<len
{
if(j==-1||s[i]==s[j])
{
i++;j++;
if(s[i]!=s[j]) next[i]=j;
else
next[i]=next[j];
}
else
j=next[j];
}
}
int index_kmp(char s[],char c[])
{
get_next(c);
int len=strlen(s);
int len1=strlen(c);
int i=0,j=0,ans=0;
int flag=-1; //标记第一取得配对的串的下标
while(i<len)
{
if(j==-1||s[i]==c[j])
{
i++;j++;
}
else
j=next[j];
if(j>=len1) //统计子串在母串中的个数,可重叠 ababa aba 2
{
ans++;
j=next[j];
//j=0 ; //统计子串在母串中的个数,不重叠ababa aba 1
if(flag==-1) //记录第一次配对成功的下标值,否则i会持续变大到最后
flag=i;
}
}
if(ans!=1)
return -1;
else
return flag-len1+1;
}
char s[10000000],c[10000000]; <span id="transmark"></span>//必须是7个0
int main()
{
char s1[10];
int n,m;
while(~scanf("%d",&n))
{
for(int i=0;i<n;i++)
{scanf("%s",s1);
s[i]=s1[0];
}
scanf("%d",&m);
for(int i=0;i<m;i++)
{
scanf("%s",s1);
c[i]=s1[0];
}
s[n]='\0';c[m]='\0';
//printf("%s*%s*",s,c);
int flag=index_kmp(s,c);//Getkmp(s,s1,n,m);
if(flag!=-1)
printf("%d %d\n",flag,flag+m-1);
else
printf("-1\n");
}
return 0;
}