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;
    }
  • 相关阅读:
    (BFS 二叉树) leetcode 515. Find Largest Value in Each Tree Row
    (二叉树 BFS) leetcode513. Find Bottom Left Tree Value
    (二叉树 BFS DFS) leetcode 104. Maximum Depth of Binary Tree
    (二叉树 BFS DFS) leetcode 111. Minimum Depth of Binary Tree
    (BFS) leetcode 690. Employee Importance
    (BFS/DFS) leetcode 200. Number of Islands
    (最长回文子串 线性DP) 51nod 1088 最长回文子串
    (链表 importance) leetcode 2. Add Two Numbers
    (链表 set) leetcode 817. Linked List Components
    (链表 双指针) leetcode 142. Linked List Cycle II
  • 原文地址:https://www.cnblogs.com/longdouhzt/p/2214453.html
Copyright © 2011-2022 走看看