【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;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

两米长弦

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值