poj 3080 Blue Jeans
题目就是找n个字符串的最长公共字串,如果有多个就输出字典序最小的一个。
我的思路就是枚举所有的字串,然后用KMP挨个字符串匹配。
#include <stdio.h> #include <string.h> char str[20][70]; char tmp[70]; char ans[70]; int f[70]; int n; void getfail(char *s) { int m = strlen(s); f[0] = 0; f[1] = 0; for (int i = 1; i < m; i++) { int j = f[i]; while (j && s[j] != s[i]) j = f[j]; f[i+1] = s[i] == s[j] ? j+1 : 0; } } bool kmp(char *s) { int m = strlen(tmp); int len = strlen(s); int j = 0; for (int i = 0; i < len; i++) { while (j && s[i] != tmp[j]) j = f[j]; if (s[i] == tmp[j]) j++; if (j == m) return true; } return false; } bool check() { for (int i = 2; i <= n; i++) { if (!kmp(str[i])) return false; } return true; } int main() { int t; scanf("%d", &t); while (t--) { scanf("%d", &n); for (int i = 1; i <= n; i++) { scanf("%s", str[i]); } int len = strlen(str[1]); bool getans = false; int anslen = 0; for (int i = len; i >= 1; i--) { for (int j = 0; j <= len-i; j++) { memset(tmp, '\0', sizeof(tmp)); strncpy(tmp, str[1]+j, i); if (i < anslen) break; if (check()) { if (!getans) { strcpy(ans, tmp); getans = true; anslen = strlen(ans); } else { if (strcmp(ans, tmp) > 0) strcpy(ans, tmp); } } } } if (strlen(ans) >= 3 && getans) puts(ans); else puts("no significant commonalities"); } }