HDU5510 Bazinga(KMP)

版权声明:欢迎转载~转载请注明出处! https://blog.csdn.net/riba2534/article/details/83217025

Problem Description

Ladies and gentlemen, please sit up straight.
Don’t tilt your head. I’m serious.
img
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 ofruizhang", and rzhang" is not a substring ofruizhang".

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,定义两个指针ij分别指向第一个串和第二个串,让s[j]包含s[i]时,指针i++,当i==j时,指针j++,当不包含时记录当前的j,指针j++.最后一个记录值就是答案.

代码

#include <bits/stdc++.h>
using namespace std;
const int N = 10000 + 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;
}

猜你喜欢

转载自blog.csdn.net/riba2534/article/details/83217025