博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
poj 3294 Life Forms
阅读量:6892 次
发布时间:2019-06-27

本文共 2553 字,大约阅读时间需要 8 分钟。

后缀数组的题目,把后缀连接起来,这个还是先二分答案,然后选取一段连续的height值,判断这些height代表的后缀有没有覆盖一半以上的字符串。

得出答案的长度之后还要在枚举连续的heigh,判断有没有答案,有的话标记其中一个。

最后再按照sa输出答案。这样就可以保证字典序。

 

#include 
#include
#include
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
<<=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
>1; if(chk(mid)) st=mid; else ed=mid-1; } if(m==1) { for(int i=1;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;}

 

 

转载地址:http://zjhbl.baihongyu.com/

你可能感兴趣的文章
关于访问Android项目中assets中的资源
查看>>
大家来解一解小学生题目......
查看>>
CentOS 6.4 & 6.5下DRBD的安装配置
查看>>
wp-setting.php文件详解
查看>>
mysqldb安装
查看>>
DOS 的XCOPY命令的应用之排除某些文件或文件夹(/EXCLUDE选项的应用)
查看>>
如何才能带动团队
查看>>
Spring中IOC和AOP的详细解释
查看>>
电机分类
查看>>
IntelliJ Idea 常用快捷键列表
查看>>
一、数组二三
查看>>
Android_触摸设备
查看>>
mysql读书笔记(三)
查看>>
实例:调用系统字体
查看>>
程序员应该重视版本控制
查看>>
提升Salt Api稳定性
查看>>
sqoop架构原理与操作
查看>>
C Primer Plus 第5章 运算符、表达式和语句 5.6 带有参数的函数
查看>>
js 函数节流与函数防抖技巧
查看>>
Netty概述
查看>>