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. MSFVENOM SHELLCODE生成备忘录

    MSFVENOM SHELLCODE生成 通用Shellcode msfvenom -a x86 --platform windows -p windows/shell_reverse_tcp LHO ...

  2. WinRAR目录穿越

    WinRAR目录穿越漏洞浅析及复现(CVE-2018-20250) 文章来源: https://www.t00ls.net/articles-50276.html EXP: https://githu ...

  3. Windows2008R2搭建共享存储服务器

    说明: 为了方便公司个部门软件.项目.文档等资料的归档和保存,实现公司内部资料共享及重要资料备份,防止因个人计算机系统故障或硬件故障导致数据丢失而造成数据无法恢复的损失,特建立共享服务器 1.在共享服 ...

  4. 标准 I/O 和管道

    1.标准输入和输出1>程序:指令+数据(指令服务于数据) 读入数据:input 输出数据:output 2>三种 I/O 设备 Linux 给程序提供三种 I/O 设备 标准输入(STDI ...

  5. Android获取CPU编号

    /** * 获取CPU序列号 * * @return CPU序列号(16位) * 读取失败为"0000000000000000" */ private static String ...

  6. Ubuntu切换为阿里镜像源

    前言 在VM虚拟机搭建Ubuntu系统学习或者测试时,常常要使用apt安装测试,但是由于系统自带的下载源在国外服务器上,下载速度慢的无法忍受.所以我们需要切换为国内镜像源,能显著加快安装包下载速度. ...

  7. python实现串口通讯小程序(GUI界面)

    python实现串口通讯小程序(GUI界面) 使用python实现串口通讯需要使用python的pyserial库来实现,这个库在安装python的时候没有自动进行安装,需要自己进行安装. 1.安装p ...

  8. linux bash 用户输入yes or no.

    脚本为script2 vim 打开脚本 内容是 对用户的键盘输入反应 sh 运行脚本,一次输入的是y ,一次输入的是n.

  9. win10下GO的环境配置

    目录 问题描述 环境变量配置 问题描述 win10 下配置 GO 语言的运行环境,主要是环境变量的设置 环境变量配置 在windows的PATH变量中添加go的可执行文件所在的目录: PATH=D:\ ...

  10. logback日志的基本使用

    logback的日志使用,有两种方式,可以在application.yml文件中配置,不过最常见的还是用一个单独的xml配置文件进行配置: 一.application.yml配置方式 logging: ...