题目大意:有M个串,每个串的长度都是60,查找这M个串的最长公共子串(连续的),长度不能小于3,如果同等长度的有多个输出字典序最小的那个。
分析:因为串不多,而且比较短,所致直接暴力枚举的第一个串的所有子串,比较暴力的做法,如果串的长度大一些就没法玩了。
代码如下:
====================================================================================
#include<stdio.h> #include<string.h> const int MAXN = 107; const int oo = 1e9+7; char s[MAXN][MAXN]; int next[MAXN]; void GetNext(char s[]) { int i=0, j=-1, N=strlen(s); next[0] = -1; while(i < N) { if(j==-1 || s[i]==s[j]) next[++i] = ++j; else j = next[j]; } } bool KMP(char a[], char s[]) { int i=0, j=0; int Na=strlen(a), Ns = strlen(s); while(i < Na) { while(j==-1 || (a[i]==s[j] && i<Na) ) i++, j++; if(j == Ns)return true; j = next[j]; } return false; } int main() { int T; scanf("%d", &T); while(T--) { int i, j, len, M, MaxLen=60; char ans[MAXN] = "Z"; scanf("%d", &M); for(i=0; i<M; i++) scanf("%s", s[i]); for(len=60; len>=3; len--) for(i=0; i<=MaxLen-len; i++) {///枚举第一个串的所有子串 char b[MAXN]={0}; strncpy(b, s[0]+i, len); GetNext(b); for(j=1; j<M; j++) { if(KMP(s[j], b) == false) break; } if(j==M && strcmp(ans, b) > 0) strcpy(ans, b); if(ans[0] != ‘Z‘ && i==MaxLen-len) i=100, len = 0;///跳出循环 } if(ans[0] == ‘Z‘) printf("no significant commonalities\n"); else printf("%s\n", ans); } return 0; }
时间: 2024-10-02 02:57:18