【Kmp】Blue Jeans POJ - 3080

CN_swords發表於2017-08-01

Link:http://poj.org/problem?id=3080

//#include <bits/stdc++.h>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <iostream>
using namespace std;
typedef long long LL;

/*
題意:找出n個串中最長的公共串,並且要求字典序最大
題解:列舉第一字串的子串
*/
const int N = 66;
int nex[N];
void getnext(string s){
    memset(nex,0,sizeof(nex));
    int len = s.length();
    nex[0] = -1;
    int k = -1;
    for(int i = 1; i < len; i++){
        while(k!=-1 && s[k+1]!=s[i])
            k = nex[k];
        if(s[k+1]==s[i])
            k++;
        nex[i] = k;
    }
}

bool Kmp(string s,string p){
    int len = s.length();
    int lenp = p.length();
    int k = -1;
    for(int i = 0; i < len; i++){
        while(k!=-1 && p[k+1]!=s[i])
            k = nex[k];
        if(p[k+1]==s[i])
            k++;
        if(k == lenp-1)
            return true;
    }
    return false;
}

struct asd{
    string s;
}ans[N],now[N*N],aa[N];
bool cmp(asd a, asd b){
    if(a.s.length() != b.s.length())
        return a.s.length() > b.s.length();
    return a.s < b.s;
}

int init(){
    int len = aa[0].s.length();
    int k = 0;
    for(int leg = 3; leg <= len; leg++){
        for(int i = 0; i+leg <= len; i++)
            now[k++].s = aa[0].s.substr(i,leg);
    }
    return k;
}

int main(){
    int T;
    scanf("%d",&T);
    while(T--){
        int n;
        cin >> n;
        for(int i = 0; i < n; i++)
            cin >> aa[i].s;
        int k = init();
        sort(now,now+k,cmp);
        int f = 0;
        for(int i = 0; i < k; i++)
        {
            //cout <<now[i].s << endl;
            getnext(now[i].s);
            int flag = 0;
            for(int j = 1; j < n; j++){
                if(!Kmp(aa[j].s,now[i].s))
                    flag = 1;
            }
            if(!flag)
            {
                f = 1;
                cout << now[i].s << endl;
                break;
            }
        }
        if(!f)  cout << "no significant commonalities" << endl;
    }
    return 0;
}


相關文章