poj 3294 Life Forms
后缀数组的题目,把后缀连接起来,这个还是先二分答案,然后选取一段连续的height值,判断这些height代表的后缀有没有覆盖一半以上的字符串。
得出答案的长度之后还要在枚举连续的heigh,判断有没有答案,有的话标记其中一个。
最后再按照sa输出答案。这样就可以保证字典序。
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
const int maxn=1e5+10000;
int r[maxn];
char a[1111];
int *rank,height[maxn],sa[maxn];
int wx[maxn],wy[maxn],cnt[maxn];
int n,m;
inline 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 n,int m)
{
r[n+1]=0;
int i,l,p,*x=wx,*y=wy,*t;
memset(cnt,0,sizeof(int)*(m+1));
for(int i=1;i<=n;i++) cnt[x[i]=r[i]]++;
for(int i=1;i<=m;i++) cnt[i]+=cnt[i-1];
for(int i=n;i>=1;i--) sa[cnt[x[i]]--]=i;
for(l=1,p=1;p<n;l<<=1,m=p)
{
for(p=1,i=n-l+1;i<=n;i++) y[p++]=i;
for(i=1;i<=n;i++)
if(sa[i]>l)
y[p++]=sa[i]-l;
memset(cnt,0,sizeof(int)*(m+1));
for(i=1;i<=n;i++) cnt[x[i]]++;
for(i=1;i<=m;i++) cnt[i]+=cnt[i-1];
for(i=n;i>=1;i--) sa[cnt[x[y[i]]]--]=y[i];
for(t=x,x=y,y=t,p=1,x[sa[1]]=1,i=2;i<=n;i++)
x[sa[i]]=cmp(y,sa[i-1],sa[i],l)?p:++p;
}
rank=x;
int j,k=0;
for(i=1;i<=n;height[rank[i++]]=k)
for(k?k--:0,j=sa[rank[i]-1];r[i+k]==r[j+k];k++);
return;
} bool fla[1111];
int c[maxn];
bool ans[maxn];
bool chk(int ret)
{
for(int i=2;i<=n;i++)
if(height[i]>=ret)
{
int j=i+1;
while(j<=n&&height[j]>=ret) j++;
j--;
memset(fla,0,sizeof(fla));
for(int k=i-1;k<=j;k++)
fla[c[sa[k]]]=1;
int cnt=0;
for(int k=1;k<=m;k++)
cnt+=fla[k];
if(cnt>m/2) return true;
i=j;
}
return false;
} int main()
{
// freopen("in.txt","r",stdin);
int ret;
int tt=0;
while(scanf("%d",&m),m)
{
if(tt++) printf("\n");
n=0;
for(int i=1;i<=m;i++)
{
scanf("%s",a+1);
ret=strlen(a+1);
for(int j=1;j<=ret;j++)
r[n+j]=a[j];
for(int j=n+1;j<=n+ret;j++)
c[j]=i;
n+=ret;
r[++n]=570+i;
}
da(r,n,680);
int st=0,ed=1111,mid;
while(st<ed)
{
mid=st+ed+1>>1;
if(chk(mid)) st=mid;
else ed=mid-1;
}
if(m==1)
{
for(int i=1;i<n;i++)
printf("%c",r[i]);
printf("\n");
}
else if(st==0)
printf("?\n");
else
{
memset(ans,0,sizeof(ans));
for(int i=1;i<=n;i++)
if(height[i]>=st)
{
int j=i+1;
while(height[j]>=st) j++;
j--;
memset(fla,0,sizeof(fla));
for(int k=i-1;k<=j;k++)
fla[c[sa[k]]]=1;
int cnt=0;
for(int k=1;k<=m;k++)
cnt+=fla[k];
if(cnt>m/2)
{
ans[sa[i-1]]=1;
}
i=j;
}
for(int i=1;i<=n;i++)
if(ans[sa[i]])
{
for(int j=1;j<=st;j++)
printf("%c",r[j+sa[i]-1]);
printf("\n");
}
}
}
return 0;
}
poj 3294 Life Forms的更多相关文章
- Poj 3294 Life Forms (后缀数组 + 二分 + Hash)
题目链接: Poj 3294 Life Forms 题目描述: 有n个文本串,问在一半以上的文本串出现过的最长连续子串? 解题思路: 可以把文本串用没有出现过的不同字符连起来,然后求新文本串的heig ...
- POJ 3294 Life Forms [最长公共子串加强版 后缀数组 && 二分]
题目:http://poj.org/problem?id=3294 Life Forms Time Limit: 5000MS Memory Limit: 65536K Total Submiss ...
- POJ 3294 Life Forms(后缀数组+二分答案)
[题目链接] http://poj.org/problem?id=3294 [题目大意] 求出在至少在一半字符串中出现的最长子串. 如果有多个符合的答案,请按照字典序输出. [题解] 将所有的字符串通 ...
- poj 3294 Life Forms - 后缀数组 - 二分答案
题目传送门 传送门I 传送门II 题目大意 给定$n$个串,询问所有出现在严格大于$\frac{n}{2}$个串的最长串.不存在输出'?' 用奇怪的字符把它们连接起来.然后求sa,hei,二分答案,按 ...
- POJ 3294 Life Forms 后缀数组+二分 求至少k个字符串中包含的最长子串
Life Forms Description You may have wondered why most extraterrestrial life forms resemble humans, ...
- 字符串(后缀数组):POJ 3294 Life Forms
Life Forms Description You may have wondered why most extraterrestrial life forms resemble humans, d ...
- poj 3294 Life Forms(后缀数组)
题意:给你最多100个字符串,求最长的且是一半以上的字符串的公共子串,如果有多个,按字典序输出. 思路:先把各个串拼起来,中间加上一个之前未出现过的字符,然后求后缀.然后根据h数组和sa数组,求出最长 ...
- poj 3294 Life Forms【SA+二分】
先加入未出现字符间隔把n个串连起来,注意如果串开的char这个间隔字符不能溢出,把这个接起来的串跑SA,二分答案k,判断的时候把连续一段he>=k的分成一组,然后看着一段是否包含了>n/2 ...
- POJ 3294 n个串中至少一半的串共享的最长公共子串
Life Forms Time Limit: 5000MS Memory Limit: 65536K Total Submissions: 12484 Accepted: 3502 Descr ...
随机推荐
- 隐私:网民最常用密码MD5解密
国内知名网络安全商瑞星公司曾发布过一项针对密码强度的专业研究报告,这项研究中列举了中国网民和美国网民最常用的密码集.研究表明,全球互联网大部分用户在密码使用中都存在着种种疏漏,一些极其简单的密码被广泛 ...
- delphi xe5 android 开发数据访问server端(二)
上一篇我们创建了一个拟给手机端访问的webservices服务 接下来创建一个返回数据集的过程,用webservices发布,供手机端调用.这里我使用firedac 1.打开上一篇自动创建的WebMo ...
- Stanford CoreNLP--Named Entities Recognizer(NER)
Standford Named Entities Recognizer(NER),命名实体识别是信息提取(Information Extraction)的一个子任务,它把文字的原子元素(Atomic ...
- 【网络流24题】 No.12 软件补丁问题(最小转移代价 最短路)
[题意] T 公司发现其研制的一个软件中有 n 个错误, 随即为该软件发放了一批共 m 个补丁程序. 每一个补丁程序都有其特定的适用环境, 某个补丁只有在软件中包含某些错误而同时又不包含另一些错误时才 ...
- ANDROID_MARS学习笔记_S03_004_getAllProviders、LOCATIONLISTENER、getBestProvider
一.代码 1.xml(1)activity_main.xml <uses-permission android:name="android.permission.ACCESS_FINE ...
- RubyGems使用
RubyGems的功能类似于Linux下的apt-get.使用它可以方便第从远程服务器下载并安装Rails. # 安装指定gem包,程序先从本机查找gem包并安装,如果本地没有,则从远程gem安装.g ...
- android使用webview上传文件(支持相册和拍照)
老夫最近需要做一个项目,需要调用服务器段的一些网页来选择文件,刚开始还挺纠结的,不知从何下手,网上大致预览了大神们走过的路,他们传统的方式都是使用一下代码: public void openFileC ...
- CF 370
A:http://codeforces.com/problemset/problem/370/A #include<stdio.h> #include<string.h> #i ...
- (转载)struct 与typdef struct的区别
(转载)http://blog.csdn.net/piratejk/article/details/3491226 1. 基本解释 typedef为C语言的关键字,作用是为一种数据类型定义一个新名字. ...
- Centos系统创建用户oracle后,用该用户登陆系统,页面加载报错GConf error
Linux 的 GConf error 解决办法 问题: Centos系统创建用户oracle后,用该用户登陆系统,页面加载报错,导致重新进入Centos系统后出现: GConf error:Fail ...