zoukankan      html  css  js  c++  java
  • poj1226 Substrings ***

    /*
    * 1226 KMP
    *
    * 用的KMP, O(n^3)
    * 由于数据规模小, 直接暴力枚举最短串的各个子串再依次与其他串KMP应该也能过 (复杂度也是O(n^3))
    *
    * 这里不直接枚举各个子串, 而是枚举子串的起点位置, 依次与其他串KMP, 记录和每个串及其反串的最大匹配长度,
    * 再以此计算这些值的最小值, 就得到该起点的子串所能达到的最大匹配长度(与刚才的方法其实差不多)
    *
    */


    #include <cstdio>
    #include <cstring>
    using namespace std;

    const int maxN = 100 + 5;
    const int maxL = 100 + 5;
    //minLen, minNum : 最短串
    int caseNum, n, minLen, minNum;
    int next[maxL];
    //串 反串
    char str[maxN][maxL], restr[maxN][maxL];


    void reverseString(int i, int len){
    for(int j=0; j<len; j++)
    restr[i][j] = str[i][len - j -1];
    restr[i][len] = 0;
    }

    //以start为起点的模式
    void preKMP(int start){
    int j, k;
    next[start] = start - 1;
    j = start, k = start - 1;
    while(j < minLen - 1){
    while(k > start - 1 && str[minNum][j] != str[minNum][k]){
    k = next[k];
    }
    j++, k++;
    if(str[minNum][j] == str[minNum][k])
    next[j] = next[k];
    else
    next[j] = k;
    }
    }


    int KMP(int t, int start){
    int i, j, ansMax, tmpMax = start;
    int tLen = strlen(str[t]);

    i = 0; j = start;
    while(i < tLen && j < minLen){

    while(j >= start && str[t][i] != str[minNum][j]){
    j = next[j];
    }
    i++, j++;
    //记录最大的j
    if(tmpMax < j)
    tmpMax = j;
    }
    ansMax = tmpMax - start;
    tmpMax = start;
    i = 0; j = start;
    while(i < tLen && j <minLen){

    while(j >= start && restr[t][i] != str[minNum][j]){
    j = next[j];
    }
    i++, j++;
    if(tmpMax < j)
    tmpMax = j;
    }
    //串与反串的最大j
    if(ansMax < tmpMax - start)
    ansMax = tmpMax - start;

    return ansMax;
    }


    int main(){
    scanf("%d", &caseNum);
    while(caseNum--){
    scanf("%d", &n);

    //注意n == 1 , 为此WA了两次!!
    if(n == 1){
    scanf("%s", str[0]);
    printf("%d\n", strlen(str[0]));
    continue;
    }

    minLen = maxL;
    for(int i=0; i<n; i++){
    scanf("%s", str[i]);
    int len = strlen(str[i]);
    reverseString(i, len);

    if(len < minLen){
    minLen = len;
    minNum = i;
    }
    }

    int tmpMin = maxL, tmp, tmpMax = -1;
    //枚举起点
    for(int i=0; i<minLen; i++){
    preKMP(i);
    tmpMin = maxL;
    for(int j=0; j<n; j++){
    if(j == minNum) continue;

    tmp = KMP(j, i);
    if(tmp < tmpMin)
    tmpMin = tmp;
    }

    if(tmpMax < tmpMin)
    tmpMax = tmpMin;
    }
    printf("%d\n", tmpMax);

    }

    return 0;
    }
  • 相关阅读:
    NameError:name ‘xrange’ is not defined
    CNN卷积核反传分析
    在定义卷积时为什么要对其中一个函数进行翻转
    Python的浮点数损失精度问题
    Python实现im2col和col2im函数
    2018.04.19
    4 Git 基础
    Clash Royale开发日志
    2018-04-12
    python urllib2
  • 原文地址:https://www.cnblogs.com/longdouhzt/p/2214453.html
Copyright © 2011-2022 走看看