【KMP】HRBUST 2036 DiabloII

DiabloII

Time Limit: 1000 MS Memory Limit: 65536 K

Description

当我们的英雄将Diablo打败之后,他打算与Diablo抗争到底,因为地域中恶魔的精神是不会消失的。最终我们的英雄失败了,Diablo占据了他的灵魂并打算前往大漠中释放被封印多年的兄弟毁灭之王Baal。古代的法师们为了不让人找到封印Baal的正确地点,建造了七座相似的古墓,但是只有一座古墓是真正封印Baal的地方,不过真正的古墓是有一个特殊的标记的。现在给出七座古墓的描述,Diablo想知道哪座古墓才是封印Baal的真正古墓。这些标记以及描述仅仅由小写字母构成。

Input

本题有多组测试数据,对于每组数据,首先输入一行小写字母,表示真正古墓的标记序列,接下来有七行,每行数据输入一组小写字母,代表对每个古墓的描述。输入处理到文件结束。注意,古墓的描述序列长度与真正古墓的标记序列长度均不超过10000。

Output

如果第k个古墓中的局部序列符合真正古墓的描述,那么就认定这个古墓是真正的古墓,如果有多个古墓符合要求,那么我们认为第一个找到的是真正的古墓。若没有古墓符合描述,那么最后一个古墓也就是7号古墓被认为是真正的古墓。你需要做的就是输出真正古墓的编号并换行。

Sample Input

abc
asvbdfaghbav
abcdfe
abcdfwr
cccccccccccccccccccccccc
edddddddddddfdcs
svgvfgsfgsfgab
erghbasfdbvnlasn

Sample Output

2

Source

2014 Winter Holiday Contest 5

Author

杨和禹

题意

RT
给出一个子串和七个主串,让你看看是否再主串中可以找到子串,并输出主串编号。
没有就输出7。

思路

KMP裸题

坑点

AC代码

#include<bits/stdc++.h>
using namespace std;

#define maxn 10006

char ptr[maxn];
char str[7][maxn];
int nt[maxn];
int plen;

void get_next(void)
{
    int k = -1;
    nt[0] = -1;
    plen = strlen(ptr);
    for(int i = 1 ; i < plen ; i++)
    {
        while(ptr[k+1]!=ptr[i]&&k > -1)
        {
            k = nt[k];
        }
        if(ptr[k+1]==ptr[i]) k++;
        nt[i] = k;
    }
}

bool kmp(char *a)
{
    int slen = strlen(a);
    int k = -1;
    for(int i = 0 ; i < slen ; i++)
    {
        while(ptr[k+1]!=a[i]&&k>-1)
        {
            k = nt[k];
        }
        if(ptr[k+1]==a[i]) k++;
        if(k == plen-1) return true;
    }
    return false;
}

void solve(void)
{
    while(~scanf("%s",ptr))
    {
        int flag = 1;
        get_next();
        for(int i = 0 ; i < 7 ; i++) scanf("%s",str[i]);
        for(int i = 0 ; i < 7 ; i++)
        {
            if(kmp(str[i])){
                cout<<i+1<<endl;
                flag = 0;
                break;
            }
        }
        if(flag) cout<<7<<endl;
    }
}

int main(void)
{
    solve();
    return 0;
}

猜你喜欢

转载自blog.csdn.net/peng0614/article/details/80158950