POJ 3080 Blue Jeans
题意:T组数据, 每次数据n个串, 求相同的连续子串,要求最长, 如果长度相同有多组, 那么输出 字典序最小的那个。
第一次字符串Hash, 写的不好, 见谅, 2333。 貌似更暴力的方法能过。
代码:
1 #include<cstdio> 2 #include<iostream> 3 #include<algorithm> 4 #include<string> 5 using namespace std; 6 #define LL long long 7 #define ULL unsigned LL 8 #define fi first 9 #define se second 10 #define lson l,m,rt<<1 11 #define rson m+1,r,rt<<1|1 12 #define max3(a,b,c) max(a,max(b,c)) 13 const int INF = 0x3f3f3f3f; 14 const LL mod = 1e9+7; 15 typedef pair<int,int> pll; 16 ULL Hash_val[15][65]; 17 ULL Hash[65]; 18 char str[15][65]; 19 string ans[60]; 20 const ULL base = 131; 21 int n; 22 void init() 23 { 24 Hash[0] = 1; 25 for(int i = 1; i <= 60; i++) 26 Hash[i] = Hash[i-1] * base; 27 } 28 void get_hash() 29 { 30 for(int i = 0; i < n; i++) 31 { 32 Hash_val[i][0] = 0; 33 for(int j = 1; j <= 60; j++) 34 Hash_val[i][j] = Hash_val[i][j-1]*base + str[i][j] - 'A' + 1; 35 } 36 } 37 ULL Get(int i, int l, int r) 38 { 39 return Hash_val[i][r] - Hash_val[i][l-1] * Hash[r-l+1]; 40 } 41 bool solve(int len) 42 { 43 int cnt = 0; 44 for(int i = 1; i+len-1 <=60; i++) 45 { 46 ULL tmp = Get(0, i, i+len-1); 47 bool flag = 0; 48 for(int j = 1; j < n; j++) 49 { 50 flag = 0; 51 for(int k = 1; k+len-1 <= 60; k++) 52 { 53 if(tmp == Get(j,k,k+len-1)) 54 flag = 1; 55 } 56 if(!flag) break; 57 } 58 if(flag) { 59 ans[cnt].clear(); 60 for(int j = i; j <= i+len-1; j++) 61 ans[cnt] += str[0][j]; 62 cnt++; 63 } 64 } 65 if(cnt) 66 { 67 sort(ans, ans+cnt); 68 cout << ans[0] << endl; 69 return true; 70 } 71 return false; 72 } 73 74 int main() 75 { 76 int t; 77 init(); 78 scanf("%d",&t); 79 while(t--) 80 { 81 scanf("%d",&n); 82 for(int i = 0; i < n; i++) 83 scanf("%s", str[i]+1); 84 get_hash(); 85 bool flag = 0; 86 for(int len = 60; len >= 3; len--){ 87 if(solve(len)){ 88 flag = 1; 89 break; 90 } 91 } 92 if(!flag) printf("no significant commonalities\n"); 93 } 94 return 0; 95 }