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 <cstdlib>
#include <cstdio>
#include <cmath>
#include <string>
#include <cstring>
#include <algorithm>
using namespace std; const int Max=501;
const int MAX=1e5+1500;
string s,ss[Max];
int n,mx;
int rnk[MAX],sa[MAX];
int tmp[MAX],c[MAX];
int h[MAX],sy[MAX]; void lcp()
{
h[0]=0;
for(int i=0,j=rnk[0],k=0; i<n-1; i++,k++)
while(k>=0&&s[i]!=s[sa[j-1]+k])
h[j]=k--,j=rnk[sa[j]+1];
} void sarank()
{
int na=256;
memset(c,0,na*sizeof(int));
n=s.size();
s[n]=1;n++;
for(int i=0; i<n; i++) rnk[i]=(int)s[i],c[rnk[i]]++;
for(int i=1; i<na; i++) c[i]=c[i]+c[i-1];
for(int i=0; i<n; i++) c[rnk[i]]--,sa[c[rnk[i]]]=i;
int j;
for(int len=1; len<n; len=len<<1)
{
for(int i=0; i<n; i++)
{
j=sa[i]-len;
if(j<0) j=j+n;
tmp[c[rnk[j]]++]=j;
}
sa[tmp[c[0]=0]]=j=0;
for(int i=1; i<n; i++)
{
if(rnk[tmp[i]]!=rnk[tmp[i-1]]||rnk[tmp[i]+len]!=rnk[tmp[i-1]+len]) c[++j]=i;
sa[tmp[i]]=j;
}
memcpy(rnk,sa,n*sizeof(int));
memcpy(sa,tmp,n*sizeof(int));
if(j>=n-1) break;
}
} int T;
bool fl[Max]; void print(int ans)
{
int tot=0,i=0;
memset(fl,false,sizeof(fl));
while(i<n)
{
tot=0;
if(h[i]>=ans)
{
while(h[i]>=ans)
{
if(!fl[sy[sa[i]]]&&sy[sa[i]]!=0&&sy[sa[i]]!=sy[sa[i-1]]) tot++,fl[sy[sa[i]]]=true;
if(!fl[sy[sa[i-1]]]&&sy[sa[i-1]]!=0&&sy[sa[i]]!=sy[sa[i-1]]) tot++,fl[sy[sa[i-1]]]=true;
i++;
}
if(tot>T/2)
{
for(int j=sa[i-1]; j<sa[i-1]+ans; j++)
cout<<s[j];
cout<<endl;
}
memset(fl,false,sizeof(fl));
}
i++;
}
} bool pd(int m)
{
int tot=0,i=1;bool f;
memset(fl,false,sizeof(fl));
while(i<n)
{
tot=0;f=false;
if(h[i]>=m)
{
while(h[i]>=m)
{
if(h[i]==m) f=true;
if(!fl[sy[sa[i]]]&&sy[sa[i]]!=0&&sy[sa[i]]!=sy[sa[i-1]]) tot++,fl[sy[sa[i]]]=true;
if(!fl[sy[sa[i-1]]]&&sy[sa[i-1]]!=0&&sy[sa[i]]!=sy[sa[i-1]]) tot++,fl[sy[sa[i-1]]]=true;
i++;
if(tot>T/2&&f) return true;
}
memset(fl,false,sizeof(fl));
}
i++;
}
return false;
} void solve()
{
int l=1,r=mx,mid,ans=0;
while(l<=r)
{
mid=(l+r)>>1;
if(pd(mid)) ans=mid,l=mid+1;
else r=mid-1;
}
if(ans) print(ans);
else printf("?\n");
} int main()
{
int sl;
bool flag=true;
while(true)
{
if(!flag) printf("\n");
else flag = false;
scanf("%d",&T);
if(T==0) break;
s="";mx=0;
for(int i=0; i<Max; i++) c[i]=h[i]=sa[i]=sy[i]=tmp[i]=rnk[i]=0;
for(int i=1; i<=T; i++)
{
cin>>ss[i];sl=ss[i].size();
for(int j=s.size(); j<s.size()+sl; j++) sy[j]=i;
s=s+ss[i]+char(i);
mx=max(mx,sl);
}
sarank(),lcp();
solve();
}
return 0;
}

Life Forms[poj3294]题解的更多相关文章

  1. 后缀数组练习4:Life Forms

    有一个细节不是特别懂,然后的话细节有点多,就是挺难发现的那一种,感谢大佬的博客 1470: 后缀数组4:Life Forms poj3294 时间限制: 1 Sec  内存限制: 128 MB提交: ...

  2. POJ3294 Life Forms —— 后缀数组 最长公共子串

    题目链接:https://vjudge.net/problem/POJ-3294 Life Forms Time Limit: 5000MS   Memory Limit: 65536K Total ...

  3. 【POJ3294】 Life Forms (后缀数组+二分)

    Life Forms Description You may have wondered why most extraterrestrial life forms resemble humans, d ...

  4. poj3294 --Life Forms

    Life Forms Time Limit: 5000MS   Memory Limit: 65536K Total Submissions: 12483   Accepted: 3501 Descr ...

  5. Life Forms (poj3294 后缀数组求 不小于k个字符串中的最长子串)

    (累了,这题做了很久!) Life Forms Time Limit: 5000MS   Memory Limit: 65536K Total Submissions: 8683   Accepted ...

  6. 【poj3294】 Life Forms

    http://poj.org/problem?id=3294 (题目链接) 题意 给定 n 个字符串,求出现在不小于 k 个字符串中的最长子串. Solution 后缀数组论文题.. 将 n 个字符串 ...

  7. 【POJ3294】Life Forms(后缀数组,二分)

    题意: n<=100 len[i]<=1000 思路:这是一道论文题 ..]of longint; ch:..]of ansistring; n,n1,l,r,mid,last,i,j,m ...

  8. POJ3294 Life Forms(后缀数组)

    引用罗穗骞论文中的话: 将n 个字符串连起来,中间用不相同的且没有出现在字符串中的字符隔开,求后缀数组.然后二分答案,用和例3 同样的方法将后缀分成若干组,判断每组的后缀是否出现在不小于k 个的原串中 ...

  9. poj3294 Life Forms(后缀数组)

    [题目链接] http://poj.org/problem?id=3294 [题意] 多个字符串求出现超过R次的最长公共子串. [思路] 二分+划分height,判定一个组中是否包含不小于R个不同字符 ...

随机推荐

  1. dubbo 分布式服务框架 介绍

    Dubbo是阿里巴巴内部的SOA服务化治理方案的核心框架,每天为2000+ 个服务提供3,000,000,000+ 次访问量支持,并被广泛应用于阿里巴巴集团的各成员站点.Dubbo自2011年开源后, ...

  2. Vue路由(vue-router)

    一.介绍 1.vue-router安装 官方文档:https://router.vuejs.org/zh/installation.html下载地址:https://unpkg.com/vue-rou ...

  3. java连接Oracle数据库,从ResultSet中提取数据出现java.sql.sqlException结果集已耗尽

    出现错误的原因是ResultSet中并没有任何东西,再调用next()方法就会出错,原因可能是oracle创建用户,表没有提交,commit即可

  4. centos7上安装docker社区版

    container(容器) docker(集装箱) 容器的优点 1. 启动速度快 2. 节省资源 3. 兼容性高 保证机器正常上网 #ping www.baidu.com CPU需要支持虚拟化 # g ...

  5. Java的开发—面向对象的7大原则之开闭原则(一)

    开闭原则(Open Close Principle) 一.定义: 软件中的(类.模块.函数等等)应该对于扩展是开放的,对于修改时关闭的.意味着一个实体允许在不改变它的源代码的前提变更它的行为 这里的软 ...

  6. dotnetcore3.1 WPF 中使用依赖注入

    dotnetcore3.1 WPF 中使用依赖注入 Intro 在 ASP.NET Core 中默认就已经集成了依赖注入,最近把 DbTool 迁移到了 WPF dotnetcore 3.1, 在 W ...

  7. .NET CORE应用程序启动

    ASP.NET Core 应用是在其 Main 方法中创建 Web 服务器的控制台应用: Main 方法调用 WebHost.CreateDefaultBuilder,通过生成器模式来创建web主机. ...

  8. 利用MySQL之federated引擎实现DBLink功能

    有时候我们需要跨库join查询,但是配置多数据源成本又太高,Oracle提供了DBLink功能,MySQL中也有类似的实现:federated-engine. MySQL中使用federated引擎的 ...

  9. 同时安装了python和3,pycharm如何切换版本

    1.打开pycharm 2.进入  File->Setting->Project:你的项目名->Project Interpreter 3.通过Project Interpreten ...

  10. JS DOM用不同方法获取节点及对节点插入、复制和移除

    操作节点的方法 appendChild() insertBefore() replaceChild() cloneNode() normalize() splitText() sppendChild( ...