Problem Description
For n given strings S1,S2,⋯,Sn, labelled from 1 to n, you should find the largest i (1≤i≤n) such that there exists an integer j (1 ≤ j < i)and Sj is not a substring of Si.
A substring of a string Si is another string that occurs in Si.
For example, “”ruiz” is a substring of “”ruizhang”“, and “”rzhang”“is not a substring of “”ruizhang”“.
Input
The first line contains an integer t (1≤t≤50) which is the number of test cases.
For each test case, the first line is the positive integer n (1≤n≤500) and in the following n lines list are the strings S1,S2,⋯,Sn.
All strings are given in lower-case letters and strings are no longer than 2000 letters.
Output
For each test case, output the largest label you get. If it does not exist, output −1.
Sample Input
4
5
ab
abc
zabc
abcd
zabcd
4
you
lovinyou
aboutlovinyou
allaboutlovinyou
5
de
def
abcd
abcde
abcdef
3
a
ba
ccc
Sample Output
Case #1: 4
Case #2: -1
Case #3: 4
Case #4: 3
题目链接:HDU 5510
题目大意:给你n个串,找出最大的第i个串,使得存在第j(0 <= j < i)个串不是i的子串
题目思路:直接暴力,但是要用 KMP 判断b是否为a的子串.
以下是代码:
#include <vector>
#include <map>
#include <set>
#include <algorithm>
#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <string>
#include <cstring>
using namespace std;
// KMP
const int MAXN = 10000;
#define _match(a, b) ((a) == (b))
int patMatch (int ls, char *str,int lp, char *pat)
{
int fail[MAXN] = {-1},i = 0, j;
for (j = 1; j < lp; j++)
{
for (i = fail[j - 1]; i >= 0 && !_match(pat[i + 1],pat[j]); i = fail[i]);
fail[j] = (_match(pat[i + 1], pat[j])) ? i + 1 : -1;
}
for (i = j = 0; i < ls && j < lp; i++)
{
if (_match(str[i],pat[j]))
{
j++;
}
else if (j)
{
j = fail[j - 1] + 1;
i--;
}
}
return j == lp ? (i - lp) : -1;
}
char s[505][2005];
int vis[2005];
int main(){
int t;
scanf("%d",&t);
int cnt = 1;
while(t--)
{
int n;
scanf("%d",&n);
memset(vis,0,sizeof(vis));
int pos = -1;
for (int i = 0; i < n; i++)
{
scanf("%s",s[i]);
}
for (int i = 0; i < n; i++)
{
for (int j = 0; j < i; j++)
{
if (vis[j]) continue;
if (patMatch(strlen(s[i]), s[i], strlen(s[j]), s[j]) == -1)
{
pos = i + 1;
}
else
{
vis[j] = 1; //如果j是i的子串,那之后判断子串的时候不需要判断j
}
}
}
printf("Case #%d: %d\n",cnt++,pos);
}
return 0;
}
//======================KMP算法模板=========================\
const int MAXN = 10000;
#define _match(a, b) ((a) == (b))
int patMatch (int ls, char *str,int lp, char *pat)
{
int fail[MAXN] = {-1},i = 0, j;
for (j = 1; j < lp; j++)
{
for (i = fail[j - 1]; i >= 0 && !_match(pat[i + 1],pat[j]); i = fail[i]);
fail[j] = (_match(pat[i + 1], pat[j])) ? i + 1 : -1;
}
for (i = j = 0; i < ls && j < lp; i++)
{
if (_match(str[i],pat[j]))
{
j++;
}
else if (j)
{
j = fail[j - 1] + 1;
i--;
}
}
return j == lp ? (i - lp) : -1;
}
//======================KMP算法模板=========================\