poj 3294 Life Forms
来源:互联网 发布:淘宝合作平台 编辑:程序博客网 时间:2024/05/17 07:32
题目链接:http://poj.org/problem?id=3294
题目思路:二分答案,然后分组,记录每组中不同串的个数,开始想复杂了,居然第次都去清空flag数组,后来用另一个数组去记录标记了的串的类型才把复杂度降下来,还有另一种记录方法就是flag数组里存储出现在哪个组里,这样就不用清空了,话说自己太傻逼了,居然还用排序来保证字典序,其实本来就是按字典序加的,本人太挫了。。还有就是可以预处理每个字符所在的串的标号,我开始还用了二分,深深地鄙视一下自己。。
#include<stdio.h>#include<stdlib.h>#include<string.h>#include<string>#include<queue>#include<algorithm>#include<vector>#include<stack>#include<list>#include<iostream>#include<map>using namespace std;#define inf 0x3f3f3f3f#define M 210000int max(int a,int b){return a>b?a:b;}int min(int a,int b){return a<b?a:b;}int sa[M],rank[M],height[M];int ta[M],tb[M],ts[M],tv[M],r[M],begin[110],end[110],flag[110],ans[M],rec[110],pos[M];char str[1100][1100];bool cmp(int *y,int a,int b,int l){ return y[a]==y[b]&&y[a+l]==y[b+l];}void da(int n,int m){ int i,j,p; int *x=ta,*y=tb; for(i=0;i<m;i++) ts[i]=0; for(i=0;i<n;i++) ts[x[i]=r[i]]++; for(i=1;i<m;i++) ts[i]+=ts[i-1]; for(i=n-1;i>=0;i--) sa[--ts[x[i]]]=i; for(j=1,p=1;p<n;j*=2,m=p) { p=0; for(i=n-j;i<n;i++) y[p++]=i; for(i=0;i<n;i++) if(sa[i]>=j) y[p++]=sa[i]-j; for(i=0;i<m;i++) ts[i]=0; for(i=0;i<n;i++) tv[i]=x[y[i]]; for(i=0;i<n;i++) ts[tv[i]]++; for(i=1;i<m;i++) ts[i]+=ts[i-1]; for(i=n-1;i>=0;i--) sa[--ts[tv[i]]]=y[i]; swap(x,y); x[sa[0]]=0; p=1; for(i=1;i<n;i++) { if(cmp(y,sa[i-1],sa[i],j)) x[sa[i]]=p-1; else x[sa[i]]=p++; } }}void calh(int n){ int i,k,tmp; for(i=1;i<=n;i++) rank[sa[i]]=i; k=0; for(i=0;i<n;i++) { tmp=sa[rank[i]-1]; for(;r[i+k]==r[tmp+k];k++) ; height[rank[i]]=k; k?--k:0; }}int check(int tp,int n,int k,int ak){ int i,j,num=0,tmp,cnt=0; for(i=0;i<tp;i++) flag[i]=0; tmp=pos[sa[1]]; flag[tmp]=1; rec[num++]=tmp; for(i=2;i<=n;i++) { if(height[i]<k) { if(ak==1&&num>tp/2) ans[cnt++]=sa[i-1]; for(j=0;j<num;j++) flag[rec[j]]=0; num=0; tmp=pos[sa[i]]; flag[tmp]=1; rec[num++]=tmp; } else { tmp=pos[sa[i]]; if(!flag[tmp]) { flag[tmp]=1; rec[num++]=tmp; } if(ak==0&&num>tp/2) return 1; } } if(ak==1&&num>tp/2) ans[cnt++]=sa[n]; if(ak==1) { for(i=0;i<cnt;i++) { for(j=0;j<k;j++) str[i][j]=r[ans[i]+j]; str[i][k]=0; } for(i=0;i<cnt;i++) printf("%s\n",str[i]); } return 0;}void getans(int l,int r,int n,int tp){ int mid; while(l<=r) { mid=(l+r)>>1; if(check(tp,n,mid,0)) l=mid+1; else r=mid-1; } if(r==0) printf("?\n"); else check(tp,n,r,1);}char s[M];int main(){ int i,j,tp,count=1,len,n,mi; while(scanf("%d",&tp),tp) { if(count>1) printf("\n"); n=0; mi=inf; for(i=0;i<tp;i++) { scanf("%s",s); len=strlen(s); mi=min(mi,len); begin[i]=n; for(j=n;j<n+len;j++) { r[j]=s[j-n]; pos[j]=i; } if(i==tp-1) { r[n+len]=0; n+=len; end[i]=n-1; } else { r[n+len]=i+129; pos[n+len]=i; n+=len+1; end[i]=n-1; } } if(tp==1) { printf("%s\n",s); continue; } da(n+1,400); calh(n); getans(1,mi,n,tp); count++; }}
- poj 3294 Life Forms
- poj 3294 Life Forms
- Poj 3294 Life Forms
- poj 3294 Life Forms
- POJ-3294-Life Forms
- POJ 3294 Life Forms
- poj-3294-Life Forms
- POJ 3294 Life Forms
- POJ 3294 Life Forms
- POJ 3294 Life Forms
- POJ - 3294 Life Forms
- poj 3294 Life Forms
- POJ 3294 Life Forms
- POJ 3294 Life Forms
- POJ - 3294 Life Forms
- POJ 3294Life Forms
- AC解 - Life Forms(POJ#3294)
- poj 3294 Life Forms(后缀数组+二分)
- (转)《我们今年二十一二岁》,写给20出头的我们……
- 移动互联网SP计费
- “穷光蛋出身,但志存高远” 联想控股董事长柳传志
- 排序算法的时间复杂度和空间复杂度
- 用Android中的ActionBar来实现分页Title栏滑块效果
- poj 3294 Life Forms
- 复杂链表的复制
- 搜索算法的感悟——解空间
- 优化上传导入名单模块之ODP
- jquery无法修改网页标题?
- HTML5 网站大观:12个优秀的 HTML5 黑色风格网站设计
- poj 2395 Out of Hay (最小生成树的最大边)
- C#winform dataGridView更新数据库
- XmlDocument 节点的三个属性:InnerText、InnerXml、FirstChild.Value介绍