HDU5510 - Bazinga(kmp+递归)

题目

Description

题解

比较关键的一点:如果a包含b,b包含c,则a包含c。
所以可以定义solve(p)为返回第p个字符串之前不能被p包含的字符串的最大位置,在递归过程中找到取最大答案。
细节详见代码。这样递归处理复杂度为O(n)。

#include <bits/stdc++.h>

#define endl '\n'
#define IOS std::ios::sync_with_stdio(0); cin.tie(0); cout.tie(0)
#define FILE freopen(".//data_generator//in.txt","r",stdin),freopen("res.txt","w",stdout)
#define FI freopen(".//data_generator//in.txt","r",stdin)
#define FO freopen("res.txt","w",stdout)
#define pb push_back
#define mp make_pair
#define seteps(N) fixed << setprecision(N) 
typedef long long ll;

using namespace std;
/*-----------------------------------------------------------------*/

ll gcd(ll a, ll b) {return b ? gcd(b, a % b) : a;}
#define INF 0x3f3f3f3f

const int N = 3e5 + 10;
const double eps = 1e-5;

int nt[N];

void getnext(char t[]) {
    int i = 0, j = -1;
    nt[i] = j;
    while(t[i]) {
        if(j == -1 || t[i]  == t[j]) {
            i++;
            j++;
            nt[i] = j;
        } else {
            j = nt[j];
        }
    }
}

bool search(char s[], char t[]) {
    int i = 0;
    int j = 0;
    bool found = false;
    while(s[i]) {
        if(j == -1 || s[i] == t[j]) {
            i++;
            j++;
            if(!t[j]) {
                found = true;
                break;
            }
        } else {
            j = nt[j];
        }
    }
    return found;
}

bool cover(char s1[], char s2[]) {
    int l1 = strlen(s1), l2 = strlen(s2);
    if(l1 < l2) return false;
    getnext(s2);
    return search(s1, s2);
}

char s[600][2000];
int ans;

int solve(int p) {
    int nt = p - 1;
    while(nt) {
        if(cover(s[p], s[nt])) {
            nt = solve(nt);
        } else {
            ans = max(ans, p);
            return nt;
        }
    }
    return 0;
}


int main() {
    IOS;
    int t;
    int cas = 0;
    cin >> t;
    while(t--) {
        ans = -1;
        int n;
        cin >> n;
        for(int i = 1; i <= n; i++) {
            cin >> s[i];
        }
        solve(n);
        cout << "Case #" << ++cas << ": " << ans << endl;
    }
}
posted @ 2020-08-14 15:25  limil  阅读(118)  评论(0编辑  收藏  举报