您的位置:首页 > Web前端

POJ3294--Life Forms 后缀数组+二分答案 大于k个字符串的最长公共子串

2015-04-22 21:38 399 查看
LifeForms

TimeLimit:5000MSMemoryLimit:65536K
TotalSubmissions:10800Accepted:2967
Description

Youmayhavewonderedwhymostextraterrestriallifeformsresemblehumans,differingbysuperficialtraitssuchasheight,colour,wrinkles,ears,eyebrowsandthelike.Afewbearnohumanresemblance;thesetypicallyhavegeometricoramorphousshapeslikecubes,oilslicksorcloudsofdust.

Theanswerisgiveninthe146thepisodeofStarTrek-TheNextGeneration,titledTheChase.Itturnsoutthatinthevastmajorityofthequadrant'slifeformsendedupwithalargefragmentofcommonDNA.

GiventheDNAsequencesofseverallifeformsrepresentedasstringsofletters,youaretofindthelongestsubstringthatissharedbymorethanhalfofthem.

Input

Standardinputcontainsseveraltestcases.Eachtestcasebeginswith1≤n≤100,thenumberoflifeforms.nlinesfollow;eachcontainsastringoflowercaselettersrepresentingtheDNAsequenceofalifeform.EachDNAsequencecontainsatleastoneandnotmorethan1000letters.Alinecontaining0followsthelasttestcase.

Output

Foreachtestcase,outputthelongeststringorstringssharedbymorethanhalfofthelifeforms.Iftherearemany,outputalloftheminalphabeticalorder.Ifthereisnosolutionwithatleastoneletter,output"?".Leaveanemptylinebetweentestcases.

SampleInput

3
abcdefg
bcdefgh
cdefghi
3
xxx
yyy
zzz
0

SampleOutput

bcdefg
cdefgh

?

题意:n个字符串,求大于n/2个字符串的最长子串。如果有多个按字典序输出。

大致思路:首先把所有字符串用不相同的一个字符隔开(用同一个字符隔开wa了好久),这里我是用数字来隔开的。
然后依次求sa,lcp。我们可以二分答案的长度,对于长度x,我们可以把后缀进行分组(lcp[i]<x时隔开),然后对于每一组判断有多少个字符串出现,如果大于n/2说明符合。。对于字典序就不用排序了,,因为我们就是按照sa数组来遍历lcp的。。所以直接得到的答案就是字典序从小到大。


#include<set>
#include<map>
#include<cmath>
#include<ctime>
#include<queue>
#include<stack>
#include<cstdio>
#include<string>
#include<vector>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
usingnamespacestd;
typedefunsignedlonglongull;
typedeflonglongll;
constintinf=0x3f3f3f3f;
constdoubleeps=1e-8;
constintM=2e6+10;
ints[M];
intsa[M],tmp[M],rank[M],lcp[M],k,len;
boolcmp(inti,intj)
{
if(rank[i]!=rank[j])
returnrank[i]<rank[j];
else
{
intx=i+k<=len?rank[i+k]:-1;
inty=j+k<=len?rank[j+k]:-1;
returnx<y;
}
}
voidbuild_sa()
{
for(inti=0;i<=len;i++)
{
sa[i]=i;
rank[i]=i<len?s[i]:-1;
}
for(k=1;k<=len;k*=2)
{
sort(sa,sa+len+1,cmp);
tmp[sa[0]]=0;
for(inti=1;i<=len;i++)
{
tmp[sa[i]]=tmp[sa[i-1]]+(cmp(sa[i-1],sa[i])?1:0);
}
for(inti=0;i<=len;i++)
{
rank[i]=tmp[i];
}
}
}
voidGet_Lcp()
{
for(inti=0;i<len;i++)
{
rank[sa[i]]=i;
}
inth=0;
lcp[0]=0;
for(inti=0;i<len;i++)
{
intj=sa[rank[i]-1];
if(h>0)
h--;
for(;i+h<len&&j+h<len;h++)
if(s[i+h]!=s[j+h])
break;
lcp[rank[i]]=h;
}
}
intvis[110],pos[M];
intans[M],tot;
intStack[M],top;
boolsolve(intx,intn)
{
intminv=inf;
intcnt=0;
boolflag=false;
for(inti=0;i<=len+1;i++)
{
if(lcp[i]<x)
{

if(cnt+(!vis[pos[sa[i-1]]])>n/2&&(minv!=inf&&minv>=x))
{
if(!flag)
tot=0;
flag=true;
ans[tot++]=sa[i-1];
}
minv=inf;
cnt=0;
memset(vis,0,sizeof(vis));
continue;
}
if(vis[pos[sa[i-1]]]==0)
{
cnt++;

}
vis[pos[sa[i-1]]]=1;
minv=min(minv,lcp[i]);

}
returntot>0&&flag;
}
intstring_len[110],c1;
voidinit()
{
c1=tot=0;
memset(vis,0,sizeof(vis));
memset(string_len,0,sizeof(string_len));
}
charcacaca[1100];
intmain()
{
#ifndefONLINE_JUDGE
freopen("in.txt","r",stdin);
//freopen("wa.txt","w",stdout);
#endif
intn,cas=1;
while(scanf("%d",&n),n)
{
if(cas!=1)
printf("\n");
cas++;
init();
len=0;
intdel=1;
for(inti=0;i<n;i++)
{
scanf("%s",cacaca);
intsub_len=strlen(cacaca);
for(intj=0;j<sub_len;j++)
{
s[len++]=cacaca[j];
}
s[len++]=M+del;
del++;
string_len[c1]=sub_len+string_len[c1-1];
if(c1)
string_len[c1]++;
c1++;
}
if(n==1)
{
for(inti=0;i<len-1;i++)
{
printf("%c",s[i]);
}
continue;
}
for(inti=0,j=0;i<len;i++)
{
if(i>=string_len[j])
{
pos[i]=-1;
j++;
continue;
}
pos[i]=j+1;
}
build_sa();
Get_Lcp();

intua=0,ub=M;
while(ua+1<ub)
{
intmid=(ua+ub)>>1;
if(mid&&solve(mid,n)==true)
{

ua=mid;
}
else
ub=mid;
}
if(tot==0)
printf("?\n");
else
{
if(ua==0)
{
printf("?\n");
continue;
}
for(inti=0;i<tot;i++)
{
for(intj=ans[i];j<ans[i]+ua;j++)
{
printf("%c",s[j]);
}
printf("\n");
}
}
}
return0;
}



                                            
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐