poj-3294-Life Forms
2014-02-12 09:18
162 查看
求多个串的,最长公共子串, 加设公共子串为 “asdf”,要求“asdf”出现的在 超过 所有串个数的一半 的 串中。。
用不同的字符,将所有串连接成一个,处理后,
二分答案,。
写的有点复杂、、
用不同的字符,将所有串连接成一个,处理后,
二分答案,。
写的有点复杂、、
#include <stdio.h> #include <math.h> #include <string.h> #include <algorithm> #include <iostream> using namespace std; #define inf 0x3f3f3f3f const int N = 110000; int r , tx , ty , rs , ranks , sa , height , rmq [20]; //rs基数排序 char s ; bool cmp(int *r, int a, int b, int len) { return (r[a] == r[b]) && (r[a + len] == r[b + len]); } void suffix(int n, int m) //n为长度,最大值小于m { int i, j, p, *x = tx, *y = ty, *t; for(i = 0; i < m; ++i) rs[i] = 0; for(i = 0; i < n; ++i) { x[i] = r[i]; ++rs[x[i]]; } for(i = 1; i < m; ++i) rs[i] += rs[i - 1]; for(i = n - 1; i >= 0; --i) sa[--rs[x[i]]] = i; for(j = p = 1; p < n; j <<= 1, m = p) { for(p = 0, i = n - j; i < n; ++i) y[p++] = i; for(i = 0; i < n; ++i) { if(sa[i] >= j) y[p++] = sa[i] - j; } for(i = 0; i < m; ++i) rs[i] = 0; for(i = 0; i < n; ++i) ++rs[x[y[i]]]; for(i = 1; i < m; ++i) rs[i] += rs[i - 1]; for(i = n - 1; i >= 0; --i) sa[--rs[x[y[i]]]] = y[i]; t = x, x = y, y = t; for(i = 1, p = 1, x[sa[0]] = 0; i < n; ++i) { if(cmp(y, sa[i - 1], sa[i], j)) x[sa[i]] = p - 1; else x[sa[i]] = p++; } } /**for(i = 0; i < n; ++i) printf("%s\n", s + sa[i]);*/ } void calheight(int n) { int i, j, k = 0; for(i = 1; i <= n; ++i) ranks[sa[i]] = i; for(i = 0; i < n; ++i) { if(k) --k; j = sa[ranks[i] - 1]; while(r[i + k] == r[j + k]) ++k; height[ranks[i]] = k; } } int f[110]; int main() { int i,j,n=0,m,ans=0; while(cin>>m,m) { int ff=0,len; int h=m/2+1; int cnt=150; n=0; for(i=0;i<m;i++) { scanf("%s",s); if(ff==0){ ff=1; len=strlen(s); } for(j=0;j<len;j++) r[n++]=s[j]; r[n++]=cnt++; } n--; r =0; suffix(n + 1, 280); calheight(n); int le=0,ri=len; while(le<ri) { m=(le+ri+1)/2; int flag=0; for(i=2;i<=n;i++) { memset(f,0,sizeof(f)); int ans=0; int ff=0; while(1) { ff++; if(sa[i]%(len+1)!=len && height[i]>=m ) { if(f[sa[i]/(len+1)]==0) { f[sa[i]/(len+1)]=1; ans++; if(ff==1){ if(f[sa[i-1]/(len+1)]==0){ f[sa[i-1]/(len+1)]=1; ans++; } } } i++; if(i>n) break; } else break; } if(ans>=h){ flag=1; break; } } if(flag==1) le=m; else ri=m-1; } if(le==0) cout<<"?"<<endl; else { for(i=2;i<=n;i++) { memset(f,0,sizeof(f)); int ans=0; int ff=0; while(1) { ff++; if(sa[i]%(len+1)!=len && height[i]>=le ) { if(f[sa[i]/(len+1)]==0) { f[sa[i]/(len+1)]=1; ans++; if(ff==1){ if(f[sa[i-1]/(len+1)]==0){ f[sa[i-1]/(len+1)]=1; ans++; } } } i++; if(i>n) break; } else break; } if(ans>=h){ for(j=sa[i-1];j<sa[i-1]+le;j++) printf("%c",r[j]); printf("\n"); } } } printf("\n"); } //system("pause"); return 0; }
相关文章推荐
- 【POJ 3294】Life Forms
- POJ 3294 Life Forms 后缀数组
- poj 3294 Life Forms(后缀数组)
- poj 3294 Life Forms (后缀数组)
- poj 3294 Life Forms (后缀数组)
- poj 3294 Life Forms(后缀数组+二分)
- POJ - 3294 Life Forms
- POJ 3294 Life Forms(后缀数组)
- POJ 3294 Life Forms
- poj3294 Life Forms(后缀数组)
- POJ-3294-Life Forms(后缀数组-不小于 k 个字符串中的最长子串)
- poj 3294 Life Forms
- POJ 3294 Life Forms 后缀数组+二分 求至少k个字符串中包含的最长子串
- poj 3294 Life Forms (后缀数组应用)
- POJ 3294 Life Forms(不小于k个字符串中的最长子串 后缀数组)
- POJ 3294 Life Forms(后缀数组)
- poj 3294(Life Forms) 2分+ 后缀数组
- poj 3294 Life Forms
- POJ 3294 Life Forms
- POJ 3294 Life Forms