hdu 5510 Bazinga(字符串kmp)

Bazinga

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 2287    Accepted Submission(s): 713

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", 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 Bazinga(字符串kmp)

problem:
给你n个字符串,求一个最大的序号i. 使1~i-1的字符串中有一个不是str[i]的子串

solve:
最开始看见想的是字典树.但是感觉很麻烦,目测会超时.
然后想的是kmp,但是优化有问题.  每次倒着往前搜,想的是如果1~i-1的所有都是i的子串. 那么搜索到i时就可以直接返回true.
如果不匹配就退出,否则就一直搜索下去. 结果TLE了....很悲伤

后来发现正确优化:如果i是k的子串. 那么匹配的时候就不需要匹配i,因为如果当前与k匹配,那么就一定与i匹配....
所以过程中标记一下不用匹配的就行了
hhh-2016-08-29 21:00:19
*/
#pragma comment(linker,"/STACK:124000000,124000000")
#include <algorithm>
#include <iostream>
#include <cstdlib>
#include <cstdio>
#include <cstring>
#include <vector>
#include <math.h>
#include <queue>
#include <set>
#include <map>
#define lson  i<<1
#define rson  i<<1|1
#define ll long long
#define clr(a,b) memset(a,b,sizeof(a))
#define scanfi(a) scanf("%d",&a)
#define scanfs(a) scanf("%s",a)
#define scanfl(a) scanf("%I64d",&a)
#define key_val ch[ch[root][1]][0]
#define inf 1e9
using namespace std;
const ll mod = 1e9+7;
const int maxn = 2005;
char str[505][2004];
int flag[maxn];
void pre_kmp(char x[],int m,int kmpnext[])
{
    int i,j;
    j = kmpnext[0] = -1;
    i = 0;
    while(i < m)
    {
        while(j != -1 && x[i] != x[j])
            j = kmpnext[j];
        if(x[++i] == x[++j])
            kmpnext[i] = kmpnext[j];
        else
            kmpnext[i] = j;
    }
}
int nex[2005];
int kmp(char x[],char y[])
{
    int m = strlen(x);
    int n = strlen(y);
    int i,j;
    clr(nex,0);
    pre_kmp(x,m,nex);
    i = j = 0;

    while(i < n)
    {
        while(j != -1 && y[i] != x[j]) j = nex[j];
        i++,j++;
        if(j >= m)
        {
            return true;
        }
    }
    return false;
}

int main()
{
    int T,n;
//    freopen("in.txt","r",stdin);
    scanfi(T);
    int cas = 1;
    while(T--)
    {
        clr(flag,0);
        scanfi(n);
        int ans = -1;
        for(int i = 1; i <= n; i++)
        {
            scanfs(str[i]);
            for(int j =1;j < i;j++)
            {
                if(flag[j])
                    continue;
                if(kmp(str[j],str[i]))
                    flag[j] = 1;
                else
                {
                    ans = i;
                }
            }
        }
        printf("Case #%d: %d\n",cas++,ans);
    }
    return 0;
}

  

时间: 2024-12-25 02:26:44

hdu 5510 Bazinga(字符串kmp)的相关文章

HDU 5510 Bazinga(KMP)

Bazinga Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total Submission(s): 4572    Accepted Submission(s): 1459 Problem Description Ladies and gentlemen, please sit up straight. Don't tilt your head. I'm serious.F

Hdu 5510 Bazinga(KMP+尺取法)

题目地址:http://acm.split.hdu.edu.cn/showproblem.php?pid=5510 思路:设两个指针l.r,对于字符串a.b.c,若a为b的子串则下次比较时可直接比较b,c.枚举r,依次比较s[l]--s[r-1]是否为s[r]的子串,若s[i]为s[r]的子串,则l++.否则答案更新为r. #include<cstdio> #include<cstring> #include<iostream> #include<algorith

hdu 5510 Bazinga 字符串+哈希

Bazinga Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total Submission(s): 2078    Accepted Submission(s): 642 Problem Description Ladies and gentlemen, please sit up straight.Don't tilt your head. I'm serious.For

【HDU 5510 Bazinga】字符串

2015沈阳区域赛现场赛第2题 题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5510 题意:给定一个由字符串组成的序列,一共n个元素,每个元素是一个不超过2000个字符的字符串.求"存在秩小于 i 且不是 i 的子串"的最大的 i (1<= i <= n). 数据范围:n [1, 500],T组输入,T [1, 50] 思路:从1到n-1枚举每个字符串str[i],判断是否有 j < i 使得str[j]不是str[i

hdu 5510 Bazinga (KMP+暴力标记)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5510 思路: 一开始直接用KMP莽了发,超时了,后面发现如果前面的字符串被后面的字符串包含,那么我们就不需要用前面的字符串去比较了,把他标记掉就好了. 实现代码: #include<iostream> #include<algorithm> #include<cstring> #include<cstdio> using namespace std; char

HDU 5510 Bazinga (KMP)

题意:给定 n 个 字符串,让你找出最大的 r,使得存在一个 sl 不是sr的子串(l  < r). 析:KMP算法,不过直接暴力就别想了,肯定TLE,所以我们考虑一下,用两个指针 l, r,如果sl 不是 sr的字串,那么们就可以更新r,继续往后,直到找到最后. 代码如下: #pragma comment(linker, "/STACK:1024000000,1024000000") #include <cstdio> #include <string>

hdu 5510 Bazinga (kmp+dfs剪枝) 2015ACM/ICPC亚洲区沈阳站-重现赛(感谢东北大学)

废话: 这道题很是花了我一番功夫.首先,我不会kmp算法,还专门学了一下这个算法.其次,即使会用kmp,但是如果暴力枚举的话,还是毫无疑问会爆掉.因此在dfs的基础上加上两次剪枝解决了这道题. 题意: 我没有读题,只是队友给我解释了题意,然后我根据题意写的题. 大概意思是给n个字符串,从上到下依次标记为1——n,寻找一个标记最大的串,要求这个串满足:标记比它小的串中至少有一个不是它的子串. 输入: 第一行输入一个整型t,表示共有t组数据. 每组数据首行一个整型n,表示有n个串. 接下来n行,每行

hdu 5510 Bazinga(暴力)

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

HDU 5510 Bazinga (字符串匹配)

题目:传送门. 题意:t 组数据,每组 n 个串,对于第 i 个串如果存在 1 到 i-1 中的某个串不是 i 的子串,那么这个第 i 个串符合题意,求 i 的最大值. 题解:KMP,AC自动机也可以,直接匹配就行.注意如果串 j 是j+1的子串,那么对于j+2来说只需要匹配j+1是不是他的子串即可,因为比匹配 j 更容易符合题意.用cin会超时,要用scanf. #include <iostream> #include <cstdio> #include <cmath>