HDU-5510-Bazinga【2015沈阳赛区】【KMP】

HDU-5510-Bazinga

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算法模板=========================\

你可能感兴趣的:(KMP,HDU,5510,2015沈阳)