数据结构实验之串三:KMP应用

数据结构实验之串三:KMP应用
Time Limit: 1000 ms Memory Limit: 65536 KiB

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
Hint
Source
windream

#include <stdio.h>
#include <stdlib.h>
#include<string.h>
int p[1000001],t[1000001],next[1000001];
void makenext(int t[],int n,int next[])
{
    int q,k;
    next[0]=0;
    for(q=1,k=0; q<n; q++)
    {
        while(k>0&&t[q]!=t[k])
        {
            k=next[k-1];
        }
        if(t[q]==t[k])
        {
            k++;
        }
        next[q]=k;
    }
}
void kmp(int p[],int m,int t[],int n,int next[])
{
    int q,k,flag=0,cn=0,w;
    makenext(t,n,next);
    for(q=0,k=0; q<m; q++)
    {
        while(k>0&&p[q]!=t[k])
        {
            k=next[k-1];
        }
        if(p[q]==t[k])
        {
            k++;
        }
        if(k==n)
        {
            cn++;
            if(cn>1)
            {
                flag=1;
                printf("-1\n");
                break;
            }
            else
            {
                w=q;
                flag=1;
            }
        }
    }//关键是这个地方啊,我的天,没看清题目,题目说唯一的l和r,也就是说光出现不行,还得只能是一个,这就要跑完这个序列,看出现了几次,并且在出现第一次的时候就把序号给他记录下来,方便到后面判断的时候,如果只是出现了一次,那就输出,但这时候下标已经变了,所以要记录下来,当次数超过一次的时候就直接输出-1,并且退出,这两种情况的flag都是1,因为不管出现了几次都是出现了
    if(cn==1)
    {
        flag=1;
        printf("%d %d\n",w-n+2,w+1);
    }
    if(flag==0)
    {
        printf("-1\n");
    }
}
int main()
{
    int m,n,i;
    scanf("%d",&m);
    memset(next,0,sizeof(next));
    for(i=0; i<m; i++)
    {
        scanf("%d",&p[i]);
    }
    scanf("%d",&n);
    for(i=0; i<n; i++)
    {
        scanf("%d",&t[i]);
    }
    kmp(p,m,t,n,next);
    return 0;
}

猜你喜欢

转载自blog.csdn.net/bhliuhan/article/details/80381320