POJ 3080 KMP练手题
思路是枚举第一个字符串中所有长度大于三的字串,再用KMP在其他串中验证是否存在这个字串,取最长字母序最小者
代码:
1 #include<stdio.h> 2 #include<iostream> 3 using namespace std; 4 5 #include<math.h> 6 #include<algorithm> 7 #include<string.h> 8 #include<stdlib.h> 9 #include<vector> 10 #include<set> 11 #include<map> 12 #include<stack> 13 #include<string> 14 #include<queue> 15 16 #define repA(p,q,i) for( int (i)=(p); (i)!=(q); ++(i) ) 17 #define repAE(p,q,i) for( int (i)=(p); (i)<=(q); ++(i) ) 18 #define repD(p,q,i) for( int (i)=(p); (i)!=(q); --(i) ) 19 #define repDE(p,q,i) for( int (i)=(p); (i)>=(q); --(i) ) 20 21 void MAIN(); 22 23 char str[11][100]; 24 char ans[100]; 25 char tmp[100]; 26 int pi[110]; 27 bool KMP(char *p, char *t); 28 void getPI(char *p); 29 30 int main() 31 { 32 //freopen("1111.in", "r", stdin); 33 //freopen("1111.out", "w", stdout); 34 MAIN(); 35 //fclose(stdout); 36 37 return 0; 38 } 39 40 void MAIN() 41 { 42 int test; scanf("%d", &test); 43 while(test--) 44 { 45 int n; scanf("%d", &n); 46 for(int i=0; i<n; ++i) 47 { 48 scanf("%s", str[i]); 49 //printf("%s\n", str[i]); 50 } 51 52 ans[0] = '\0'; 53 54 int len = strlen(str[0]); 55 int end; 56 //cout<<len<<endl; 57 for(int sub = 3; sub <=len; ++sub) 58 { 59 //cout<<sub<<endl; 60 end = len-sub; 61 for(int s = 0; s <= end; ++s) 62 { 63 //cout<<s; 64 for(int k = 0; k<sub; ++k) 65 tmp[k] = str[0][s+k]; 66 67 tmp[sub] = '\0'; 68 //printf("%s\n", tmp); 69 bool flag = true; 70 for(int i=1; i<n; ++i) 71 { 72 //cout<<"OK"<<endl; 73 if(! KMP(tmp, str[i]) ) 74 { 75 flag = false; 76 break; 77 } 78 } 79 //cout<<sub<<endl; 80 if(flag) 81 { 82 // cout<<"OK"<<endl; 83 int tq = strlen(ans); 84 if(sub > tq) 85 strcpy(ans, tmp); 86 else if(sub == tq) 87 { 88 if(strcmp(ans, tmp) > 0) 89 strcpy(ans, tmp); 90 } 91 92 } 93 94 } 95 } 96 97 if(strlen(ans) < 3) printf("no significant commonalities\n"); 98 else printf("%s\n", ans); 99 100 } 101 102 return ; 103 } 104 105 bool KMP(char *p, char *t) 106 { 107 getPI(p); 108 //cout<<"PIOK"; 109 int n = strlen(t); 110 int m = strlen(p); 111 112 int q=0; 113 repA(0,n,i) 114 { 115 while(q>0 && p[q] != t[i]) 116 q = pi[q-1]; 117 if(p[q] == t[i]) 118 ++q; 119 if(q == m) 120 return true; 121 122 } 123 //cout<<"KMPOK"<<endl; 124 return false; 125 } 126 127 void getPI(char *p) 128 { 129 pi[0] = 0; 130 int k=0; 131 int m = strlen(p); 132 repA(1, m, q) 133 { 134 135 while(k>0 && p[k]!=p[q]) 136 k = pi[k-1]; 137 if(p[k] == p[q]) 138 ++k; 139 pi[q] = k; 140 141 } 142 143 return ; 144 }
To Be The Best Of Yourself
浙公网安备 33010602011771号