HDU5510 Bazinga(KMP)
Problem Description
Ladies and gentlemen, please sit up straight.
Don’t tilt your head. I’m serious.
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", andrzhang" 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
思路
给你了n
个字符串,每个字符串是s[i]
,让你找一个最大的i
使得s[i]
包含之前的任意一个字符串不是s[i]
的子串。
匹配的过程用优化版的kmp
,定义两个指针i
和j
分别指向第一个串和第二个串,让s[j]
包含s[i]
时,指针i++
,当i==j
时,指针j++
,当不包含时记录当前的j
,指针j++
.最后一个记录值就是答案.
代码
#include <bits/stdc++.h>
using namespace std;
const int N = 500 + 10;
int nxt[N];
string s[N];
void get_next(string p)
{
int len = p.length();
int j = 0, k = -1;
nxt[0] = -1;
while (j < len)
{
if (k == -1 || p[j] == p[k])
{
j++;
k++;
if (p[j] != p[k])
nxt[j] = k;
else
nxt[j] = nxt[k];
}
else
k = nxt[k];
}
}
int get_index(string s, string p)
{
int slen = s.length();
int plen = p.length();
get_next(p);
int i = 0, j = 0;
while (i < slen && j < plen)
{
if (j == -1 || s[i] == p[j])
{
i++;
j++;
}
else
j = nxt[j];
}
if (j == plen)
return i - j;
return -1;
}
void solve()
{
int n;
cin >> n;
for (int i = 1; i <= n; i++)
{
cin >> s[i];
}
int i = 1, j = 2, ans = -1;
while (j <= n)
{
if (get_index(s[j], s[i]) != -1)
{
i++;
if (i == j)
j++;
}
else
{
ans = j;
j++;
}
}
cout << ans << endl;
}
int main()
{
//freopen("in.txt", "r", stdin);
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
int t, q = 1;
cin >> t;
while (t--)
{
cout << "Case #" << q++ << ": ";
solve();
}
return 0;
}