POJ3294--Life Forms
来源:互联网 发布:网络推广电话营销话术 编辑:程序博客网 时间:2024/05/19 19:29
Description
You may have wondered why most extraterrestrial life forms resemble humans, differing by superficial traits such as height, colour, wrinkles, ears, eyebrows and the like. A few bear no human resemblance; these typically have geometric or amorphous shapes like cubes, oil slicks or clouds of dust.
The answer is given in the 146th episode of Star Trek - The Next Generation, titled The Chase. It turns out that in the vast majority of the quadrant's life forms ended up with a large fragment of common DNA.
Given the DNA sequences of several life forms represented as strings of letters, you are to find the longest substring that is shared by more than half of them.
Input
Standard input contains several test cases. Each test case begins with 1 ≤ n ≤ 100, the number of life forms. n lines follow; each contains a string of lower case letters representing the DNA sequence of a life form. Each DNA sequence contains at least one and not more than 1000 letters. A line containing 0 follows the last test case.
Output
For each test case, output the longest string or strings shared by more than half of the life forms. If there are many, output all of them in alphabetical order. If there is no solution with at least one letter, output "?". Leave an empty line between test cases.
Sample Input
3abcdefgbcdefghcdefghi3xxxyyyzzz0
Sample Output
bcdefgcdefgh?
#include <iostream>#include <cstdio>#include <cstring>#include <cmath>#include <vector>using namespace std;#define maxn 140080#define inf 0x3f3f3f3fint key[maxn],belong[140080];char str[maxn];bool vis[120];int sa[maxn],t[maxn],t2[maxn],c[maxn];int height[maxn],Rank[maxn];/*用SA模板注意在最后添加一个比所有字符都小的字符。key[n] = 0;build_sa(key,n+1,m);getHeight(key,n+1);显然sa[0] 就是最后那个位置。。。height[i] 表示 sa[i] 和 sa[i-1] 的最长公共前缀。。*/void build_sa(int * s,int n,int m){int i,*x = t,*y = t2;for(i = 0;i < m;i++)c[i] = 0;for(i = 0;i < n;i++)c[ x[i] = s[i] ]++;for(i = 1;i < m;i++)c[i] += c[i-1];for(i = n-1;i >= 0;i--)sa[--c[x[i]]] = i;for(int k = 1;k <= n;k <<= 1){int p = 0;for(i = n - k;i < n;i++)y[p++] = i;for(i = 0;i < n;i++)if(sa[i] >= k)y[p++] = sa[i] - k;for(i = 0;i < m;i++)c[i] = 0;for(i = 0;i < n;i++)c[ x[y[i]] ]++;for(i = 0;i < m;i++)c[i] += c[i-1];for(i = n-1;i >= 0;i--)sa[--c[x[y[i]]]] = y[i];//根据sa和y数组计算新的数y组swap(x,y);p = 1;x[sa[0]] = 0;for(i = 1;i < n;i++)x[sa[i]] = y[sa[i-1]] == y[sa[i]] && y[sa[i-1] + k] == y[sa[i] + k] ? p-1:p++;if(p >= n)break;m = p;}}void getHeight(int * s,int n){int i,j,k = 0;for(i = 0;i < n;i++)Rank[sa[i]] = i;for(i = 0;i < n;i++){if(k) k--;int j = sa[Rank[i]-1];while(s[i+k] == s[j+k])k++;height[Rank[i]] = k;}}inline int max(int a,int b){return a>b?a:b;}bool Judge(int n,int len,int num){int cnt = 0;memset(vis,0,sizeof(vis));vis[0] = 1;if(!vis[belong[sa[0]]])cnt++;vis[belong[sa[0]]] = 1;for(int i = 1;i < n;i++){if(height[i] >= len){if(!vis[belong[sa[i]]])cnt++;}else{memset(vis,0,sizeof(vis));cnt = 0;vis[0] = 1;if(!vis[belong[sa[i]]])cnt++;}vis[belong[sa[i]]] = 1;if(cnt >= num)return 1;}return 0;}//////Judge 没有问题。。。void Print(int n,int len,int num){int cnt = 0;memset(vis,0,sizeof(vis));vis[0] = 1;if(!vis[belong[sa[0]]])cnt++;vis[belong[sa[0]]] = 1;for(int i = 1;i < n;i++){if(height[i] < len){if(cnt >= num){for(int j = sa[i-1];j < sa[i-1] + len;j++)printf("%c",key[j] - 15);printf("\n");}cnt = 0;memset(vis,0,sizeof(vis));vis[0] = 1;}if(!vis[belong[sa[i]]])cnt++;vis[belong[sa[i]]] = 1;}if(cnt >= num){for(int i = sa[n-1];i < sa[n-1] + len;i++)printf("%c",key[i] - 15);printf("\n");}}int main(){//freopen("in.txt","r",stdin);int n;int f = 0;while(scanf("%d",&n) != EOF && n){if(f)printf("\n");else f = 1;memset(belong,0,sizeof(belong));int pos = 0,scat = 1;int l = 0,r = 0;for(int i = 0;i < n;i++){scanf("%s",str);int len = strlen(str);r = max(len,r);for(int j = pos;j < pos + len;j++){key[j] = (int)str[j - pos] + 15;belong[j] = i + 1;}key[pos + len] = scat++;pos += len + 1;}if(n == 1){printf("%s\n",str);continue;}key[pos - 1] = 0;build_sa(key,pos,150);getHeight(key,pos);int maxlen = 0;while(l <= r){int mid = (l + r) >> 1;if(Judge(pos,mid,n/2+1)){maxlen = mid;l = mid + 1;}else r = mid - 1;}if(maxlen == 0){printf("?\n");}else Print(pos,maxlen,n/2+1);}return 0;}
- Life Forms poj3294
- POJ3294--Life Forms
- poj3294 Life Forms
- poj3294 Life Forms
- POJ3294-Life Forms
- Poj3294 Life Forms
- POJ3294:Life Forms(后缀数组)
- 后缀数组 - poj3294 Life Forms
- poj3294 Life Forms - 后缀数组
- POJ3294 Life Forms 【后缀数组】
- 【POJ3294】Life Forms【后缀数组】【二分】
- poj3294 Life Forms(后缀数组)
- [POJ3294]Life Forms(后缀数组+二分)
- POJ3294-Life Forms(后缀数组)
- poj3294 Life Forms(后缀数组+二分答案)
- POJ3294——Life Forms 后缀数组
- POJ3294---Life Forms(后缀数组,二分+给后缀分组)
- poj3294 Life Forms(后缀数组+大于k/2个字符串中含有的最长公共子串)
- Vijos P1034家族
- CrtDumpMemoryLeaks报告程序中的内存泄露问题(简单示例代码)
- android多国语言资源命名
- U-Boot(2) 汇编知识学习
- arcengine C# 按行政区范围加载图层数据
- POJ3294--Life Forms
- WebShell
- DTD
- Win7屏蔽".exe已停止工作"对话框
- 360随身wifi产品分析
- U-Boot(3) 汇编学习要点之 .word
- oracle SQL单行函数1-字符函数汇总
- 如何引用 System.Runtime.Serialization.Json(VS 2008)
- oracle SQL单行函数2-数值、日期和转换函数汇总