题意:给你n个的串,求出它们的最长公共子串,如果不存在这个子串,则输出“IDENTITY LOST”,如果存在多个最长公共子串,则输出字典序最小的那一个。
思路:枚举+KMP。与poj3080类似,详情见poj3080
#include<iostream> #include<cstring> using namespace std; const int nMax = 4002; const int mMax = 202; char text[nMax][mMax], pat[mMax]; int n, ma, lent[nMax], lenp, next[mMax]; void get_next() { int j=1, k=0; next[0] = -1; next[1]=0; while(j< lenp) { if(pat[j] == pat[k]) { next[j+1]=k+1; j++; k++; } else if (k==0) { next[j+1]=0; j++; } else k=next[k]; } } void KMP() { int k, m, i, j; get_next(); ma = 200; for(k = 1; k < n; k ++) { i = 0; j = 0; m = 0; while(i < lent[k] && j < lenp) { if(j == -1 || text[k][i] == pat[j]) { i ++; j ++; } else j = next[j]; if(j > m) m = j; } if(m < ma) ma = m; } } int main() { int i; char result[mMax], tmp[mMax]; while(scanf("%d", &n) && n) { for(i = 0; i < n; i ++) { scanf("%s", text[i]); lent[i] = strlen(text[i]); } int ans = 0; for(i = 0; i < lent[0]; i ++) { strcpy(pat, text[0] + i); lenp = lent[0] - i; KMP(); if(ans < ma) { ans = ma; strncpy(result, text[0] + i, ans); result[ans] = '\0'; } else if(ans == ma) { strncpy(tmp, text[0] + i, ans); tmp[ans] = '\0'; if(strcmp(tmp, result) < 0) strcpy(result, tmp); } } if(ans == 0) printf("IDENTITY LOST\n"); else printf("%s\n", result); } return 0; }