t
Time Limit: 1000ms Memory limit: 65536K 有疑问?点这里^_^
题目描述
有n个小朋友,每个小朋友手里有一些糖块,现在这些小朋友排成一排,编号是由1到n。现在给出m个数,能不能唯一的确定一对值l和r(l <= r),使得这m个数刚好是第l个小朋友到第r个小朋友手里的糖块数?
输入
首先输入一个整数n,代表有n个小朋友。(0<n<=10^6)
之后一行输入n个整数,第i个整数代表第i个小朋友手里的糖块数。
然后输入一个整数m,代表现在m个数组成一个连续的序列。(0<m<=min(10^5,n) )
之后一行输入m个整数。(输入的每个数都会在0到10^9之间)
输出
如果能唯一的确定一对l,r的值,那么输出这两个值,否则输出-1
示例输入
5 1 2 3 4 5 3 2 3 4
示例输出
2 4
提示
算法:KMP算法 直接套用模板 一次就A了 但是比赛的时候想到用KMP了 就是没有想到用模板 不过模板真的很好
用的<SDUTOJ 246模板代码>
#include<stdio.h>
#include<string.h>
#define inf 1100000
int next[inf];
long long s[inf],a[inf];
long long n,m;
void fun()
{
long long i,j;
i = 0;
j = -1;
next[0] = -1;
while(i < m)
{
if(j == -1 || s[i] == s[j])
{
i++;
j++;
next[i] = j;
}
else
{
j = next[j];
}
}
}
long long kmp()
{
long long i,j,t1;
int flag=0;
j = i =0;
while(i < n)
{
if(s[i] == a[j] || j == -1)
{
i++;
j++;
}
else
{
j = next[j];
}
if(j==m && flag==0)
{
t1=i-m+1;
j=0;
flag=1;
}
else if(j==m)
{
return 0;
}
}
return t1;
}
int main()
{
long long i,j;
while(~scanf("%lld",&n))
{
for(i=0;i<n;i++)
{
scanf("%lld",&s[i]);
}
scanf("%lld",&m);
for(i=0;i<m;i++)
{
scanf("%lld",&a[i]);
}
fun();
long long p = kmp();
if(p==0)
{
printf("-1\n");
}
else
{
printf("%lld %lld\n",p,p+m-1);
}
}
return 0;
}