poj 3294 后缀数组 多字符串中不小于 k 个字符串中的最长子串
| Time Limit: 5000MS | Memory Limit: 65536K | |
| Total Submissions: 16223 | Accepted: 4763 |
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 ?
Source
//论文题,将 n 个字符串连起来,中间用不相同的且没有出现在字符串中的字符隔开,求后缀数组。然后二分答案,将后缀
//分成若干组,判断每组的后缀是否出现在不小于 k 个的原串中。这个做法的时间复杂度为 O(nlogn)。
//数组要开大一些不然re。
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
const int MAXN=;
int sa[MAXN+],he[MAXN+],ra[MAXN+],xx[MAXN+],yy[MAXN+],buc[MAXN+];
int s[MAXN+],id[MAXN+],vis[],q[];
int len,m,top;
void get_suf()
{
int *x=xx,*y=yy;
for(int i=;i<m;i++) buc[i]=;
for(int i=;i<len;i++) buc[x[i]=s[i]]++;
for(int i=;i<m;i++) buc[i]+=buc[i-];
for(int i=len-;i>=;i--) sa[--buc[x[i]]]=i;
for(int k=;k<=len;k<<=){
int p=;
for(int i=len-;i>=len-k;i--) y[p++]=i;
for(int i=;i<len;i++) if(sa[i]>=k) y[p++]=sa[i]-k;
for(int i=;i<m;i++) buc[i]=;
for(int i=;i<len;i++) buc[x[y[i]]]++;
for(int i=;i<m;i++) buc[i]+=buc[i-];
for(int i=len-;i>=;i--) sa[--buc[x[y[i]]]]=y[i];
swap(x,y);
p=;x[sa[]]=;
for(int i=;i<len;i++){
if(y[sa[i-]]==y[sa[i]]&&y[sa[i-]+k]==y[sa[i]+k])
x[sa[i]]=p-;
else x[sa[i]]=p++;
}
if(p>=len) break;
m=p;
}
for(int i=;i<len;i++) ra[sa[i]]=i;
int k=;
for(int i=;i<len;i++){
if(ra[i]==) { he[]=; continue; }
if(k) k--;
int j=sa[ra[i]-];
while(s[i+k]==s[j+k]&&i+k<len&&j+k<len) k++;
he[ra[i]]=k;
}
}
bool solve(int mid,int n)
{
memset(vis,,sizeof(vis));
int l=,qq[],cnt=,st=-;
for(int i=;i<len;i++){
if(he[i]<mid){
if(cnt>n/&&st!=-) qq[++l]=st;
memset(vis,,sizeof(vis));
cnt=;st=-;
}else{
if(st==-) st=i-;
if(!vis[id[sa[i]]]) cnt++;
vis[id[sa[i]]]=;
if(!vis[id[sa[i-]]]) cnt++;
vis[id[sa[i-]]]=;
}
}
if(cnt>=n/&&st!=-) qq[++l]=st;
if(l){
top=l;
for(int i=;i<=l;i++) q[i]=qq[i];
return ;
}else return ;
}
int main()
{
int n;
char ch[];
while(scanf("%d",&n)&&n){
len=;
top=;
int r=,l=,ans=;
for(int i=;i<=n;i++){
scanf("%s",ch);
int tmp=strlen(ch);
r=max(r,tmp);
for(int j=;j<tmp;j++){
s[len]=ch[j]-'a';
id[len++]=i;
}
s[len]=i+;
id[len++]=;
}
m=;
get_suf();
while(l<=r){
int mid=(l+r)>>;
if(solve(mid,n)) { ans=mid;l=mid+; }
else r=mid-;
}
if(ans==){
printf("?\n\n");
continue;
}
for(int i=;i<=top;i++){
for(int j=sa[q[i]];j<=sa[q[i]]+ans-;j++) printf("%c",s[j]+'a');
printf("\n");
}
printf("\n");
}
return ;
}
poj 3294 后缀数组 多字符串中不小于 k 个字符串中的最长子串的更多相关文章
- poj 3294 后缀数组+二分
题目大意: 给定n个字符串,求出现在不小于k个字符串中的最长子串 基本思路: 二分长度,统计个数,一般套路,就是这个跟说好的不一样啊,我非得开2倍才不re,真他妈不爽,先二分找出长度,然后根据长度输出 ...
- POJ 3294 后缀数组
题目链接:http://poj.org/problem?id=3294 题意:给定n个字符串,求一个最长子串要求在超过一半的字符串中出现过. 如果多解按字典序输出 思路:根据<<后缀数组— ...
- POJ-3294-Life Forms(后缀数组-不小于 k 个字符串中的最长子串)
题意: 给定 n 个字符串,求出现在不小于 k 个字符串中的最长子串. 分析: 将 n 个字符串连起来,中间用不相同的且没有出现在字符串中的字符隔开,求后缀数组. 然后二分答案,将后缀分成若干组,判断 ...
- poj 3693 后缀数组 重复次数最多的连续重复子串
Maximum repetition substring Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 8669 Acc ...
- SPOJ PHRASES 每个字符串至少出现两次且不重叠的最长子串
Description You are the King of Byteland. Your agents have just intercepted a batch of encrypted ene ...
- poj 3415 后缀数组 两个字符串中长度不小于 k 的公共子串的个数
Common Substrings Time Limit: 5000MS Memory Limit: 65536K Total Submissions: 11469 Accepted: 379 ...
- POJ - 3294~Relevant Phrases of Annihilation SPOJ - PHRASES~Substrings POJ - 1226~POJ - 3450 ~ POJ - 3080 (后缀数组求解多个串的公共字串问题)
多个字符串的相关问题 这类问题的一个常用做法是,先将所有的字符串连接起来, 然后求后缀数组 和 height 数组,再利用 height 数组进行求解. 这中间可能需要二分答案. POJ - 3294 ...
- Life Forms POJ - 3294(不小于k个字符串中的最长子串)
题意: 求不小于字符串一半长度个字符串中的最长字串 解析: 论文题例11 将n个字符串连起来,中间用不相同的且没有出现在字符串中的字符隔开, 求后缀数组, 然后二分答案变为判定性问题, 然后判断每组的 ...
- poj 2774 后缀数组 两个字符串的最长公共子串
Long Long Message Time Limit: 4000MS Memory Limit: 131072K Total Submissions: 31904 Accepted: 12 ...
随机推荐
- Python列表解析
列表解析 根据已有列表,高效创建新列表的方式. 列表解析是Python迭代机制的一种应用,它常用于实现创建新的列表,因此用在[]中. 语法: [expression for iter_val in i ...
- Data truncation: Truncated incorrect DOUBLE value:
在写sql查询语句queryRunner.update(connection,"update account set balance=? where name=?",account ...
- TeamWork#3,Week5,Scrum Meeting 11.14
根据最近项目出现的问题,我们明确了需要补充的工作,添加了几项任务. 成员 已完成 待完成 彭林江 由于网站信息更新,正在调整爬虫程序结构 更换爬虫结构 郝倩 由于网站信息更新,正在调整爬虫程序结构 更 ...
- 今日事——Sprint计划会议
一. Sprint需求: 解屏提醒部分 界面设计 登录功能 备忘功能 成就系统 二.工作认领: 因有成员请假回家,所以延后认领,目前主要任务是学习如何在andriod平台开发并搭建开发环境. 网上 ...
- Sprint会议2
昨天:准备查找安卓APP开发的有关资料,安装有关软件 今天:自己制作一个安卓小程序,熟悉一下操作 遇到问题:安装遇到问题,环境配置出现问题
- Mininet-Wifi 多接入点(Access Point)实验
实验简介 这个实验来自Mininet-Wifi用户手册.在本实验中,我们会创建一个有三个AP的线式拓扑,并有三个站点(station)与每个AP通过无线相连.将通过这个时间简单演示一些Mininet ...
- 【Coursera】因子分析模型
一.协方差矩阵 协方差矩阵为对称矩阵. 在高斯分布中,方差越大,数据分布越分散,方差越小发,数据分布越集中. 在协方差矩阵中,假设矩阵为二维,若第二维的方差大于第一维的方差,则在图像上的体现就是:高斯 ...
- Eclipse下高亮显示Freemarker文件
让eclipse高亮显示freemarker文件有两种方式,一种是安装JBoss的插件,一种是用JSP编辑器打开freemarker的文件.我使用第二种方式来完成. 打开eclipse,点击windo ...
- AG-Admin微服务框架入门
AG-Admin微服务框架入门 @qq群:一群: 837736451 二群 169824183 一 概要介绍 AG-Admin后台地址:https://gitee.com/minull/ace-s ...
- 作死实验,删除libc.so.6
参考https://www.cnblogs.com/fjping0606/p/4551475.html https://www.cnblogs.com/weijing24/p/5890031.html ...