poj3294 --Life Forms
Time Limit: 5000MS | Memory Limit: 65536K | |
Total Submissions: 12483 | Accepted: 3501 |
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<cstdio>
#include<cstring>
#include<cmath>
#include<string>
#include<algorithm>
#include<iostream>
#define maxn 200005
int ws[maxn],wa[maxn],sa[maxn],num[maxn],n,wv[maxn],rank[maxn];
int h[maxn],wb[maxn],sum[maxn],m;
char str[][];
bool cmp(int *r,int a,int b,int l){
return r[a]==r[b]&&r[a+l]==r[b+l];
} void da(int *r,int *sa,int n,int m){
int *t,*x=wa,*y=wb,i,j,p;
for (i=;i<m;i++) ws[i]=;
for (i=;i<n;i++) x[i]=r[i];
for (i=;i<n;i++) ws[x[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;j*=,m=p){
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++) wv[i]=x[y[i]];
for (i=;i<n;i++) ws[wv[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,i=,p=,x[sa[]]=;i<n;i++)
x[sa[i]]=cmp(y,sa[i],sa[i-],j)?p-:p++;
}
}
void cal(int *r,int n){
int i,j,k=;
for (int i=;i<=n;i++) rank[sa[i]]=i;
for (int i=;i<n;h[rank[i++]]=k)
for (k?k--:,j=sa[rank[i]-];r[i+k]==r[j+k];k++);
}
int getid(int k){
int l=,r=n-,mid;
while (l<r){
mid=(l+r)/;
if (sum[mid]<k) {
l=mid+;
}
else
r=mid;
}
return l;
} bool check(int len,int out=){
int i=n+,j,k,id,cnt;
bool f[maxn];
while (){
while (i<=m&&h[i]<len) i++;
if (i>m) break;
memset(f,,sizeof f);
id=getid(sa[i-]);
f[id]=true;
cnt=;
while (i<=m&&h[i]>=len){
id=getid(sa[i]);
if (!f[id]){
f[id]=true;
cnt++;
}
i++;
}
if (out==){
if (*cnt>n) return true;
}
else
if (*cnt>n){
for (k=sa[i-],j=;j<len;k++,j++){
printf("%c",num[k]+'a'-);
}
printf("\n");
} }
return false;
}
int main(){
freopen("tx.in","r",stdin);
int i,j,k;
while (scanf("%d",&n)&&n!=){
scanf("%s",str[]);
if (n==){
printf("%s\n\n",str[]);
continue;
}
sum[]=strlen(str[]);
for (i=;i<n;i++){
scanf("%s",str[i]);
sum[i]=sum[i-]+strlen(str[i])+;
}
for (k=i=;i<n;i++){
for (j=;j<strlen(str[i]);j++){
num[k++]=str[i][j]-'a'+;
}
num[k++]=i;
}
m=k-;
da(num,sa,m+,);
cal(num,m);
int l=,r=m,mid;
while (l<r){
mid=(l+r+)/;
if (check(mid)) l=mid;
else r=mid-;
}
if (l==) printf("?\n\n");
else {
check(l,);
printf("\n");
}
}
}
后缀数组
poj3294 --Life Forms的更多相关文章
- POJ3294 Life Forms —— 后缀数组 最长公共子串
题目链接:https://vjudge.net/problem/POJ-3294 Life Forms Time Limit: 5000MS Memory Limit: 65536K Total ...
- POJ3294 Life Forms(后缀数组)
引用罗穗骞论文中的话: 将n 个字符串连起来,中间用不相同的且没有出现在字符串中的字符隔开,求后缀数组.然后二分答案,用和例3 同样的方法将后缀分成若干组,判断每组的后缀是否出现在不小于k 个的原串中 ...
- poj3294 Life Forms(后缀数组)
[题目链接] http://poj.org/problem?id=3294 [题意] 多个字符串求出现超过R次的最长公共子串. [思路] 二分+划分height,判定一个组中是否包含不小于R个不同字符 ...
- POJ-3294 Life Forms n个字符串中出现超过n/2次的最长子串(按字典序依次输出)
按照以前两个字符串找两者的最长公共子串的思路类似,可以把所有串拼接到一起,这里为了避免讨论LCP跨越多个串需需要特别处理的问题用不同的字符把所有串隔开(因为char只有128位,和可能不够用,更推荐设 ...
- 2018.11.28 poj3294 Life Forms(后缀数组+双指针)
传送门 后缀数组经典题目. 我们先把所有的字符串都接在一起. 然后求出hththt数组和sasasa数组. 然后对于sasasa数组跑双指针统计答案. 如果双指针包括进去的属于不同字符串的数量达到了题 ...
- POJ3294 Life Forms 【后缀数组】
生命形式 时间限制: 5000MS 内存限制: 65536K 提交总数: 16660 接受: 4910 描述 你可能想知道为什么大多数外星人的生命形式与人类相似,不同的是表面特征,如身高,肤色 ...
- POJ3294 Life Forms(二分+后缀数组)
给n个字符串,求最长的多于n/2个字符串的公共子串. 依然是二分判定+height分组. 把这n个字符串连接,中间用不同字符隔开,跑后缀数组计算出height: 二分要求的子串长度,判断是否满足:he ...
- 【POJ3294】 Life Forms (后缀数组+二分)
Life Forms Description You may have wondered why most extraterrestrial life forms resemble humans, d ...
- Life Forms (poj3294 后缀数组求 不小于k个字符串中的最长子串)
(累了,这题做了很久!) Life Forms Time Limit: 5000MS Memory Limit: 65536K Total Submissions: 8683 Accepted ...
随机推荐
- Codeforces 545C Woodcutters
http://codeforces.com/contest/545/problem/C 题目大意: 给n棵树的在一维数轴上的坐标,以及它们的高度.现在要你砍倒这些树,树可以向左倒也可以向右倒,砍倒的树 ...
- [VBA]用一个简单例子说明如何在Excel中自定义函数
Excel中的函数无疑是强大的,但是再强大的战士也有他脆弱的脚后跟[1].这两天在使用Excel的时候遇到了一个需求,要在某一个单元格里面自动计算今天是星期几(如显示 Today is Tuesday ...
- dictionary (key-value) (map容器)
#dictionary可以保存不同类型的值 menu = {'fish0':14.50} list = [] menu['fish1'] = 10.1 # Adding new key-value p ...
- Hash Map (Hash Table)
Reference: Wiki PrincetonAlgorithm What is Hash Table Hash table (hash map) is a data structure use ...
- 面试题32.从1到n整数中1出现的次数
题目:输入一个整数n,求从1到n这n个整数的十进制表示中1出现的次数.例如输入12,从 1到12这些整数中包含1的数字中1,10,11和12,1一共出现了5次 本题可以直接变量1到n的n个数然后分别计 ...
- 嵌入式项目数据解决方案之sqlite
sqlite当前的版本为3
- JavaScript Function 函数深入总结
整理了JavaScript中函数Function的各种,感觉函数就是一大对象啊,各种知识点都能牵扯进来,不单单是 Function 这个本身原生的引用类型的各种用法,还包含执行环境,作用域,闭包,上下 ...
- windows环境下nutch2.x 在eclipse中实现抓取数据存进mysql详细步骤
nutch2.x 在eclipse中实现抓取数据存进mysql步骤 最近在研究nutch,花了几天时间,也遇到很多问题,最终结果还是成功了,在此记录,并给其他有兴趣的人提供参考,共同进步. 对nutc ...
- 在Spring aop中的propagation的7种配置的意思
<tx:method name="find*" read-only="true" propagation ="NOT_SUPPORTED&quo ...
- 站点建设10个最好的响应的HTML5滑块插件
大多数的最佳响应的HTML5滑块插件能够使用移动应用程序,站点建设项目,以及Web开发项目提供一些令人兴奋的功能,如无限的动画效果,百分之中的一个百响应布局设计和很多其它. 1.别急!慢慢来 功能丰富 ...