POJ 3450 Corporate Identity(KMP)

本文介绍了一种求解多个字符串间最长公共子串的有效算法,采用KMP算法对每个字符串的后缀进行匹配,找到匹配最小值的最大值即为所求。代码实现清晰,并通过实例演示了整个过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 

【题目链接】 http://poj.org/problem?id=3450

 

【题目大意】

  求k个字符串的最长公共子串,如果有多个答案,则输出字典序最小的。

 

【题解】

  我们对第一个串的每一个后缀和其余所有串做kmp,取匹配最小值的最大值就是答案。

 

【代码】

#include <cstring>
#include <cstdio>
#include <algorithm>
const int N=4050,M=210; 
using namespace std;
int nxt[M],n;
char dict[N][M];
void get_nxt(char *a,int n){
    int i,j;
    for(nxt[0]=j=-1,i=1;i<n;nxt[i++]=j){
        while(~j&&a[j+1]!=a[i])j=nxt[j];
        if(a[j+1]==a[i])j++;
    }
}
int LongestPre(char *s,int len){
    get_nxt(s,len);
    for(int i=1;i<n;i++){
        char *p=dict[i];
        int ans=0;
        for(int j=-1;*p;p++){
            while(~j&&s[j+1]!=*p)j=nxt[j];
            if(s[j+1]==*p){
                j++; ans=max(ans,j+1);
            }if(j==len-1)j=nxt[j];
        }len=min(len,ans);
    }return len;
}
int main(){
    while(scanf("%d",&n)&&n){
        getchar();
        for(int i=0;i<n;i++)gets(dict[i]);
        int len=strlen(dict[0]),ans=0,pos=0;
        for(int i=0;i<len;i++){
            int tmp=LongestPre(dict[0]+i,len-i);
            if(tmp>=ans){
                if(tmp>ans)ans=tmp,pos=i;
                else{
                    bool flag=1;
                    for(int t=0;t<ans;t++){
                        if(dict[0][pos+t]>dict[0][i+t])break;
                        else if(dict[0][pos+t]<dict[0][i+t]){flag=0;break;}
                    }if(flag)pos=i;
                }
            }
        }if(ans){
            for(int i=0;i<ans;i++)putchar(dict[0][pos+i]);
                puts("");
        }else puts("IDENTITY LOST");
    }return 0;
}

  

转载于:https://www.cnblogs.com/forever97/p/poj3450.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值