Life Forms

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

3
abcdefg
bcdefgh
cdefghi
3
xxx
yyy
zzz
0

Sample Output

bcdefg
cdefgh ?

  注意一些细节就好。

 #include <iostream>
#include <cstring>
#include <cstdio>
using namespace std;
const int maxn=;
char s[maxn];
int r[maxn],Wa[maxn],Wb[maxn],Wv[maxn],Ws[maxn];
int rank[maxn],lcp[maxn],belong[maxn],sa[maxn];
bool cmp(int *p,int i,int j,int l){
return p[i]==p[j]&&p[i+l]==p[j+l];
}
void DA(int n,int m){
int i,j,p,*x=Wa,*y=Wb,*t;
for(i=;i<m;i++)Ws[i]=;
for(i=;i<n;i++)++Ws[x[i]=r[i]];
for(i=;i<m;i++)Ws[i]+=Ws[i-];
for(i=n-;i>=;i--)sa[--Ws[x[i]]]=i; for(j=,p=;p<n;m=p,j<<=){
for(p=,i=n-j;i<n;i++)y[p++]=i;
for(i=;i<n;i++)
if(sa[i]>=j)
y[p++]=sa[i]-j;
for(i=;i<m;i++)Ws[i]=;
for(i=;i<n;i++)++Ws[Wv[i]=x[y[i]]];
for(i=;i<m;i++)Ws[i]+=Ws[i-];
for(i=n-;i>=;i--)
sa[--Ws[Wv[i]]]=y[i];
for(t=x,x=y,y=t,x[sa[]]=,i=,p=;i<n;i++)
x[sa[i]]=cmp(y,sa[i],sa[i-],j)?p-:p++;
}
} void LCP(int n){
int i,j,k=;
for(i=;i<=n;i++)rank[sa[i]]=i;
for(i=;i<n;lcp[rank[i++]]=k)
for(k?k--:k,j=sa[rank[i]-];r[i+k]==r[j+k];k++);
}
int tot,tim,vis[maxn];
bool Judge(int n,int x,int g){
int tmp=;++tim;
for(int i=;i<=n;i++){
if(lcp[i]<x)
tmp=,++tim;
else{
if(vis[belong[sa[i]]]!=tim)
tmp++,vis[belong[sa[i]]]=tim;
if(vis[belong[sa[i-]]]!=tim)
tmp++,vis[belong[sa[i-]]]=tim;
if(tmp>g)return true;
}
}
return false;
} void Solve(int n,int x,int g){
int tmp=,tag=;++tim;
for(int i=;i<=n;i++){
if(lcp[i]<x)
tmp=,++tim,tag=;
else{
if(vis[belong[sa[i]]]!=tim)
tmp++,vis[belong[sa[i]]]=tim;
if(vis[belong[sa[i-]]]!=tim)
tmp++,vis[belong[sa[i-]]]=tim;
if(tmp>g&&!tag){
for(int j=;j<x;j++)
printf("%c",r[sa[i-]+j]);
printf("\n");
tag=;
}
}
}
return;
} int main(){
while(~scanf("%d",&tot)&&tot){ int len=,lo=,hi=;
for(int i=;i<=tot;i++){
scanf("%s",s);
for(int j=;s[j];j++){
belong[len]=i;
r[len++]=s[j];
if(!s[j+])hi=min(hi,j+);
}
belong[len]=+i;
r[len++]='z'+i;
}
r[len]=;
DA(len+,);
LCP(len); while(lo<=hi){
int mid=(lo+hi)>>;
if(Judge(len,mid,tot/))lo=mid+;
else hi=mid-;
}
if(hi>=)
Solve(len,hi,tot/);
else
printf("?\n");
printf("\n");
}
return ;
}

最新文章

  1. 学习SpringMVC——你们要的REST风格的CRUD来了
  2. django for monkey(chapter one)
  3. linux 如何开机自动运行sh脚本
  4. Driver development
  5. 【Shell脚本学习16】Shell if else语句
  6. 【BestCoder】【Round#29】
  7. c#通过Dotpeek调试dll
  8. The connection to adb is down, and a severe error has occured.问题解决
  9. 香蕉派 BPI-M1+ 双核开源硬件单板计算机
  10. Php连接及读取和写入mysql数据库的常用代码
  11. java Log4j日志配置详解大全
  12. HTML页面中JavaScript能获取到的各种屏幕大小信息
  13. PCB载流你必须知道的那些事儿
  14. 网络yum源制作
  15. 在IDEA中配置spring boot项目的热更新
  16. [No0000159]C# 7 中的模范和实践
  17. 同一局域网运行两套LVS
  18. Appium Python API
  19. Javascript-多个数组是否有一样值
  20. sqlserver 死锁相关

热门文章

  1. dedecms 5.7文章编辑器附件上传图标不显示
  2. 使用js使表单自动提交
  3. jetty服务器访问系统的域名
  4. ios手势复习值之换图片-转场动画(纯代码)
  5. 重要性!important
  6. 使用soapUI代替WSDL2JAVA生成cxf HTTPS 客户端调用代码
  7. 我用Emacs,后来转向Vim——Vim学习之Vim键盘图(绝对值得珍藏)
  8. div浮动框居于浏览器窗口中间
  9. D题 - A+B for Input-Output Practice (III)
  10. 单个ViewController支持横屏,其他全竖屏方法-b