本题可以使用暴力法直接求解,思路也挺简单的,不过实现起来也挺麻烦的。
本题最暴力直接使用strstr过。 这里使用hash表的方法过,这种方法好像有个学名的,主要思路就是把一个需要查找的字符串赋予一个数值,那么就可以把一串字符串的比较转换为一个值的比较了,那么就可以加速字符串的查找了。
#include <stdio.h> #include <string.h> #include <stdlib.h> const long long MOD = (int)(1E9+7);//如果增加mod的话,会有很大几率出错的,本题就不能增加MOD,否则一直WA,不使用MOD就马上AC了 const int MAX_N = 61; const int MAX_M = 11; const int ALP_LEN = 4; const int SIGNIFICANT = 3; const char *intToChar = "ATGC"; short charToInt[256]; char dict[MAX_M][MAX_N]; char subStr[MAX_N]; long long finger; bool searchFinger(char *txt, int L, int len) { long long F = 0; long long K = 1; int i = 0; for (; i < L; i++) { F = ((F*5)+charToInt[txt[i]]); K = K*5; } if (F == finger) return true; for (int j = 0; i < len; j++, i++) { F = ((F*5)+charToInt[txt[i]]); F = (F-K*charToInt[txt[j]]); if (F == finger) return true; } return false; } int main() { charToInt['A'] = 1;//不能从0开始,如果使用hash法 charToInt['T'] = 2; charToInt['G'] = 3; charToInt['C'] = 4; int T, n; scanf("%d", &T); while (T--) { scanf("%d", &n); getchar(); // get rid of '\n' for (int i = 0; i < n; i++) { gets(dict[i]); } int len = MAX_N - 1; int maxLen = 0; char res[MAX_N] = {'\0'}; for (int i = 0; i < len; i++)//search every start position { finger = 0; for (int L = 1; L <= len-i; L++)//every substring { subStr[L-1] = dict[0][i+L-1]; subStr[L] = '\0'; finger = ((finger*5)+(charToInt[subStr[L-1]])); int j = 1; for (; j < n; j++) { if (!searchFinger(dict[j], L, len)) break; } if (j != n) break;//break to the next start position if (L > maxLen || (L==maxLen && strcmp(res, subStr)>0)) {//alphabetic first strcpy(res, subStr); maxLen = L; } } } if (maxLen < SIGNIFICANT) { puts("no significant commonalities"); } else { printf("%s\n", res); } } return 0; }
使用strstr也可以,时间效率是一样的:
#include <stdio.h> #include <string.h> #include <stdlib.h> const int MAX_N = 61; const int MAX_M = 11; const int ALP_LEN = 4; const int SIGNIFICANT = 3; char dict[MAX_M][MAX_N]; char subStr[MAX_N]; int main() { int T, n; scanf("%d", &T); while (T--) { scanf("%d", &n); getchar(); // get rid of '\n' for (int i = 0; i < n; i++) { gets(dict[i]); } int len = MAX_N - 1; int maxLen = 0; char res[MAX_N] = {'\0'}; for (int i = 0; i < len; i++)//search every start position { for (int L = 1; L <= len-i; L++)//every substring { subStr[L-1] = dict[0][i+L-1]; subStr[L] = '\0'; int j = 1; for (; j < n; j++) { if (!strstr(dict[j], subStr)) break; } if (j != n) break;//break to the next start position if (L > maxLen || (L==maxLen && strcmp(res, subStr)>0)) {//alphabetic first strcpy(res, subStr); maxLen = L; } } } if (maxLen < SIGNIFICANT) { puts("no significant commonalities"); } else { printf("%s\n", res); } } return 0; }
使用strstr的第二种方法:
const int MAX_N = 61; const int MAX_M = 11; const int ALP_LEN = 4; const int SIGNIFICANT = 3; char dict[MAX_M][MAX_N]; char subStr[MAX_N]; int main() { int T, n; scanf("%d", &T); while (T--) { scanf("%d", &n); getchar(); // get rid of '\n' for (int i = 0; i < n; i++) { gets(dict[i]); } int len = MAX_N - 1; int maxLen = 0; char res[MAX_N]; for (int i = 0; i < len; i++)//search every start position { int len2 = len-i; strncpy(subStr, dict[0]+i, len2); for (int L = len2; L > 0; L--)//every substring { subStr[L] = '\0'; int j = 1; for (; j < n; j++) { if (!strstr(dict[j], subStr)) break; } if (j == n) { if (L > maxLen || (L==maxLen && strcmp(res, subStr)>0)) {//alphabetic first strcpy(res, subStr); maxLen = L; } break; //break to the next start position } } } if (maxLen < SIGNIFICANT) { puts("no significant commonalities"); } else { printf("%s\n", res); } } return 0; }
POJ 3080 Blue Jeans 三种暴力法
时间: 2024-11-20 07:03:44