Problem Description
有n个小朋友,每个小朋友手里有一些糖块,现在这些小朋友排成一排,编号是由1到n。现在给出m个数,能不能唯一的确定一对值l和r(l <= r),使得这m个数刚好是第l个小朋友到第r个小朋友手里的糖块数?
Input
首先输入一个整数n,代表有n个小朋友。下一行输入n个数,分别代表每个小朋友手里糖的数量。
之后再输入一个整数m,代表下面有m个数。下一行输入这m个数。
Output
如果能唯一的确定一对l,r的值,那么输出这两个值,否则输出-1
Sample Input
5
1 2 3 4 5
3
2 3 4
Sample Output
2 4
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int text[10000000];
int a[10000000];
int n,m;
void get(int a[],int next[])
{
int i=0;
int j=-1;
next[0]=-1;
while(i<n)
{
if(j==-1||a[i]==a[j])
{
i++;
j++;
next[i]=j;
}
else
{
j=next[j];
}
}
}
int kmp(int text[],int a[])
{
int next[n+1];
get(a,next);
int i=0,j=0,index=0;
while(i<n&&j<m)
{
if(text[i]==a[j])
{
i++;
j++;
}
else
{
index=index+j-next[j];
if(next[j]!=-1)
{
j=next[j];
}
else
{
i++;
j=0;
}
}
}
if(j==m)
{
return index+1;
}
else
{
return -1;
}
}
int main()
{
int i;
while(~scanf("%d",&n))
{
for(i=0;i<n;i++)
{
scanf("%d",&text[i]);
}
scanf("%d",&m);
for(i=0;i<m;i++)
{
scanf("%d",&a[i]);
}
int t=kmp(text,a);
if(t==-1)
{
printf("-1\n");
}
else
{
int tt=kmp(text+t,a);
if(tt==-1)
{
printf("%d %d\n",t,t+m-1);
}
else
{
printf("-1\n");
}
}
}
return 0;
}
#include<stdio.h>
#include <stdlib.h>
int a[10000000];
int b[10000000];
int next[10000000];
int n,m;
void getnext()
{
int i=0;
int j=-1;
next[0]=-1;
while(i<n)
{
if(j==-1||a[i]==b[j])
{
i++;
j++;
next[i]=j;
}
else
{
j=next[j];
}
}
}//三化一循环,循环内部两条件,循环条件改变
int KMP(int a[])
{
int j=0,i=0;
while(j<m&&i<n)
{
if(a[i]==b[j])
{
i++;
j++;
}
else
{
if(j==0)
{
i++;
}
else
{
j=next[j-1]+1;
}
}
}
if(j<m)
return -1;
else
return i-m+1;//返回起始匹配成功位置
}//二化一循环,循环内部两条件,else里面还有两条件,循环完了if else来返回
int main()
{
int i,k,t;
scanf("%d",&n);
for(i=0; i<n; i++)
{
scanf("%d",&a[i]);
}
scanf("%d",&m);
for(i=0; i<m; i++)
{
scanf("%d",&b[i]);
}//两个输入
getnext();
k=KMP(a);//调用两次函数
if(k==-1)
{
printf("-1\n");
}
else
{
t=KMP(a+k);//再次调用匹配以后的位置
if(t==-1)
printf("%d %d\n",k,k+m-1);//输出起始位置和末位置
else
printf("-1\n");
}
return 0;
}
浙公网安备 33010602011771号