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;
}