Substrings - HDU 1238(最大共同子串)

题目大意:给你N个串,求出来他们的最大公共子串的长度(子串反过来也算他们的子串)。

 

分析:很久以前就做过这道题,当时是用的strstr做的,不过相同的都是枚举了子串......还是很暴力,希望下次遇到类似的题目我已经掌握高效的方法了。

==============================================================================

#include<stdio.h>
#include<string.h>

const int MAXN = 107;
const int oo = 1e9+7;
const int mod = 10007;

char s[MAXN][MAXN];
int next[MAXN];

void GetNext(char s[], int N)
{
    int i=0, j=-1;
    next[0] = -1;

    while(i < N)
    {
        if(j==-1 || s[i]==s[j])
            next[++i] = ++j;
        else
            j = next[j];
    }
}
bool KMP(char a[], char b[])
{
    int i=0, j=0;
    int Na = strlen(a);
    int Nb = strlen(b);

    GetNext(b, Nb);

    while(i < Na)
    {
        while(j==-1 || (a[i]==b[j] && i<Na))
            i++, j++;
        if(j == Nb)return true;

        j = next[j];
    }

    return false;
}
bool OK(char a[], char s[])
{
    if(KMP(a, s) == true)
        return true;
    strrev(s);

    return KMP(a, s);
}
int main()
{
    int T;

    scanf("%d", &T);

    while(T--)
    {
        int i, j, k, N, len=oo, ans=0;
        char a[MAXN];///保存最短的那个串

        scanf("%d", &N);

        for(i=1; i<=N; i++)
        {
            scanf("%s", s[i]);

            int M = strlen(s[i]);

            if(len > M)
            {
                len = M;
                strcpy(a, s[i]);
            }
        }

        for(i=1; i<=len; i++)
        for(j=0; i+j<=len; j++)
        {
            char b[MAXN] = {0};

            strncpy(b, a+j, i);

            for(k=1; k<=N; k++)
            {
                if(OK(s[k], b) == false)
                    break;
            }

            if(k > N)
                j=len, ans = i;
        }

        printf("%d\n", ans);
    }

    return 0;
}
时间: 2024-10-06 07:37:01

Substrings - HDU 1238(最大共同子串)的相关文章

poj 1226 hdu 1238 Substrings 求若干字符串正串及反串的最长公共子串 2002亚洲赛天津预选题

题目:http://poj.org/problem?id=1226 http://acm.hdu.edu.cn/showproblem.php?pid=1238 其实用hash+lcp可能也可以,甚至可能写起来更快,不过我没试,我最近在练习后缀数组,所以来练手 后缀数组的典型用法之一----------------后缀数组+lcp+二分 思路:1.首先将所有的字符串每读取一个,就将其反转,作为一组,假设其下标为i到j,那么cnt[i]到cnt[j]都标记为一个数字(这个数字意思是第几个读入的字符

HDU 1238

好吧,这题直接搜索就可以了,不过要按照长度最短的来搜,很容易想得到. 记得ACM比赛上有这道题,呃..不过,直接搜..呵呵了,真不敢想. 1 #include <iostream> 2 #include <cstdio> 3 #include <string.h> 4 #include <algorithm> 5 using namespace std; 6 7 char str[105][105]; 8 char s1[105],s2[105]; 9 10

UVA 12718 Dromicpalin Substrings(寻找字符串连续子串的回文)

转载请注明出处:http://blog.csdn.net/u012860063 题目链接:http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=4456 题意:寻找给出字符串的字串中是回文的个数(注意:字串中字母换位置后能组成回文也要算在内,例如:aab之类的可以换位置为:aba 也是一个回文). 思路:只需统计每个字母出现的次数,再统计出现次数中

HDU 1238 Substrings (水)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1238 枚举最短字符串的的每个子串然后暴力....我能怎么办,我也很无奈啊 代码: 1 #define _CRT_SECURE_NO_WARNINGS 2 #include <functional> 3 #include <algorithm> 4 #include <iostream> 5 #include <cstring> 6 #include <ca

hdu 1238 Substrings (暴搜,枚举)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1238 Substrings Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 8391    Accepted Submission(s): 3862 Problem Description You are given a number of

HDU 1238 (暴力反转KMP)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1238 题意:给定n个字符串,求它们的最长连续子序列,值得注意的是,求的的子序列可以是反转的. 题解:直接记录出最短的字符串作为匹配串,其实用第一个也应该是可以的,然后不断的缩小其长度,知道能够匹配成功,如果匹配不成功,则把字符串反转,再找一次即可. Time:31ms Memory:1712KB reverse(s,s+n):字符串反转函数. 代码如下: 1 #include<cstdio> 2

hdu 1238 字符串处理 暴力

Substrings Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 13779    Accepted Submission(s): 6689http://acm.hdu.edu.cn/showproblem.php?pid=1238 Problem Description You are given a number of case-

SPOJ - DISUBSTR Distinct Substrings (不相同的子串的个数)

Distinct Substrings  Time Limit: 159MS   Memory Limit: 1572864KB   64bit IO Format: %lld & %llu Description Given a string, we need to find the total number of its distinct substrings. Input T- number of test cases. T<=20;Each test case consists of

HDU 1238 Substing

思路: 1.找出n个字符串中最短的字符串Str[N] 2.从长到短找Str[N]的子子串 subStr[N],以及subStr[N]的反转字符串strrev(subStr[N]):(从长到短是做剪枝处理) 3.用strstr()函数遍历所有的字符串,看是否含有此子子串subStr[N]或strrev(subStr[N]):只要有一个字符串不包含subStr[N]或strrev(subStr[N])就放弃这个子串,尝试下一个: 4.找到第一个满足要求的就输出strlen(subStr[N])或者s