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>
#include <cstdlib>
#include <cmath>
#include <iostream>
#include <cstring>
#include <set>
#include <queue>
#include <algorithm>
#include <vector>
#include <map>
#include <cctype>
#include <cmath>
#include <stack>
#define debug puts("+++++")
//#include <tr1/unordered_map>
#define freopenr freopen("in.txt", "r", stdin)
#define freopenw freopen("out.txt", "w", stdout)
using namespace std;
//using namespace std :: tr1;

typedef long long LL;
typedef pair<int, int> P;
const int INF = 0x3f3f3f3f;
const double inf = 0x3f3f3f3f3f3f;
const LL LNF = 0x3f3f3f3f3f3f;
const double PI = acos(-1.0);
const double eps = 1e-8;
const int maxn = 2e3 + 5;
const LL mod = 2147493647;
const int N = 1e6 + 5;
const int dr[] = {-1, 0, 1, 0, 1, 1, -1, -1};
const int dc[] = {0, 1, 0, -1, 1, -1, 1, -1};
const char *Hex[] = {"0000", "0001", "0010", "0011", "0100", "0101", "0110", "0111", "1000", "1001", "1010", "1011", "1100", "1101", "1110", "1111"};
inline LL gcd(LL a, LL b){  return b == 0 ? a : gcd(b, a%b); }
inline int gcd(int a, int b){  return b == 0 ? a : gcd(b, a%b); }
inline int lcm(int a, int b){  return a * b / gcd(a, b); }
int n, m;
const int mon[] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
const int monn[] = {0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
inline int Min(int a, int b){ return a < b ? a : b; }
inline int Max(int a, int b){ return a > b ? a : b; }
inline LL Min(LL a, LL b){ return a < b ? a : b; }
inline LL Max(LL a, LL b){ return a > b ? a : b; }
inline bool is_in(int r, int c){
    return r >= 0 && r < n && c >= 0 && c < m;
}
int f[maxn];
char s[505][maxn];

void getFail(char *P){
    int m = strlen(P);
    f[0] = f[1] = 0;
    for(int i = 1; i < m; ++i){
        int j = f[i];
        while(j && P[i] != P[j])  j = f[j];
        f[i+1] = P[i] == P[j] ? j+1 : 0;
    }
}

bool match(char *T, char *P){
    int n = strlen(T), m = strlen(P);
    getFail(P);
    int j = 0;
    for(int i = 0; i < n; ++i){
        while(j && P[j] != T[i]) j = f[j];
        if(P[j] == T[i])  ++j;
        if(j == m) return true;
    }
    return false;
}
int main(){
    int T;  cin >> T;
    for(int kase = 1; kase <= T; ++kase){
        scanf("%d", &n);
        int ans = -1;
        int l = 1, r = 2;
        for(int i = 1; i <= n; ++i)  scanf("%s", s+i);
        while(r <= n){
            while(l < r){
                if(match(s[r], s[l]))  ++l;
                else { ans = r;  break; }
            }
            ++r;
        }
        printf("Case #%d: %d\n", kase, ans);
    }
    return 0;
}
时间: 2024-10-14 11:29:45

HDU 5510 Bazinga (KMP)的相关文章

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+dfs剪枝) 2015ACM/ICPC亚洲区沈阳站-重现赛(感谢东北大学)

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

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

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】字符串

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 (字符串匹配)

题目:传送门. 题意: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>

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(暴力)

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