Poj 3080 Blue Jeans + Hdu 2328 Corporate Identity (后缀数组 字典序最小的最长公共子串)
2013-08-07 21:58
477 查看
Poj 3080 Blue Jeans
题意:求n个长度为60的字符串的最长连续公共子串,2<=n<=10
1、 最长公共串长度小于3不输出
2、 若出现等长的最长的子串,则输出字典序最小的串
思路:和Poj 3294 Life Forms差不多,只不过变成了只输出第一个。
据说暴力也可以过。。。暴力法参考代码及测试数据:http://blog.csdn.net/lyy289065406/article/details/6647262
尤其注意最后一组测试数据
[b]Hdu 2328 Corporate Identity
和上面那题基本一样。
题意:求n个长度为60的字符串的最长连续公共子串,2<=n<=10
1、 最长公共串长度小于3不输出
2、 若出现等长的最长的子串,则输出字典序最小的串
思路:和Poj 3294 Life Forms差不多,只不过变成了只输出第一个。
据说暴力也可以过。。。暴力法参考代码及测试数据:http://blog.csdn.net/lyy289065406/article/details/6647262
尤其注意最后一组测试数据
#include <cstdio> #include <cstring> #include <algorithm> using namespace std; #define max(a,b) ((a)>(b)?(a):(b)) #define min(a,b) ((a)<(b)?(a):(b)) const int N = int(1e4)+100; int cmp(int *r,int a,int b,int l){ return (r[a]==r) && (r[a+l]==r[b+l]); } int wa ,wb ,ws ,wv ; int rank ,height ; void DA(int *r,int *sa,int n,int m){ int i,j,p,*x=wa,*y=wb,*t; for(i=0;i<m;i++) ws[i]=0; for(i=0;i<n;i++) ws[x[i]=r[i]]++; for(i=1;i<m;i++) ws[i]+=ws[i-1]; for(i=n-1;i>=0;i--) sa[--ws[x[i]]]=i; for(j=1,p=1;p<n;j*=2,m=p) { for(p=0,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<n;i++) wv[i]=x[y[i]]; for(i=0;i<m;i++) ws[i]=0; for(i=0;i<n;i++) ws[wv[i]]++; for(i=1;i<m;i++) ws[i]+=ws[i-1]; for(i=n-1;i>=0;i--) sa[--ws[wv[i]]]=y[i]; for(t=x,x=y,y=t,p=1,x[sa[0]]=0,i=1;i<n;i++) x[sa[i]]=cmp(y,sa[i-1],sa[i],j)?p-1:p++; //printf("p = %d\n", p ); } } void calheight(int *r,int *sa,int n){ // memset(height,0,sizeof(height)); // memset(rank,0,sizeof(rank)); int i,j,k=0; for(i=1;i<=n;i++) rank[sa[i]]=i; for(i=0;i<n; height[rank[i++]] = k ) for(k?k--:0,j=sa[rank[i]-1]; r[i+k]==r[j+k]; k++); } int data ,loc ,sa ,temp ; int n,q,ans ,id; char str[105]; bool vis[105]; bool Judge (int x) { int i,j; bool flag=false; for (i=1;i<=n;i++) { int cnt=0; int L=i; while (L<=n && height[L]<x) L++; if (L>n) break; int R=L; while (R<=n && height[R]>=x) R++; memset(vis,false,sizeof(vis)); for (j=L-1;j<=R-1;j++) if (loc[sa[j]]!=-1) vis[loc[sa[j]]]=true; for (j=1;j<=q;j++) if (vis[j]) cnt++; if (cnt==q) if (flag) ans[++id]=sa[L-1]; else { ans[id=1]=sa[L-1]; flag=true; } i=R; } return flag; } void Input () { int i,de=170;//分隔符 n=0; scanf("%d",&q); memset(data,0,sizeof(data)); for (int id=1;id<=q;id++) { scanf("%s",str); int len=strlen(str); for (i=0;i<len;i++) { loc =id; data[n++]=(int)str[i]; } loc =-1; data[n++]=de++; //注意分隔符需变化 } data =0; } int main () { #ifdef ONLINE_JUDGE #else freopen("read.txt","r",stdin); #endif int T; scanf("%d",&T); for (int Cas=1;Cas<=T;Cas++) { Input (); DA(data,sa,n+1,300); calheight(data,sa,n); int low=0,high=n,mid,res=0; while (low<high) { mid = (low+high)>>1; if (Judge(mid)) res=mid,low=mid+1; else high=mid; } if (res<3) printf("no significant commonalities\n"); else { int k=ans[1]; //字典序最小一定第一个 for (int j=0;j<res;j++) //res子串长度 printf("%c",(char)data[k+j]); printf("\n"); } } return 0; }
[b]Hdu 2328 Corporate Identity
和上面那题基本一样。
#include <cstdio> #include <cstring> #include <algorithm> using namespace std; #define max(a,b) ((a)>(b)?(a):(b)) #define min(a,b) ((a)<(b)?(a):(b)) const int N = int(8e5)+100; int cmp(int *r,int a,int b,int l){ return (r[a]==r[b]) && (r[a+l]==r[b+l]); } int wa ,wb ,ws ,wv ; int rank ,height ; void DA(int *r,int *sa,int n,int m){ int i,j,p,*x=wa,*y=wb,*t; for(i=0;i<m;i++) ws[i]=0; for(i=0;i<n;i++) ws[x[i]=r[i]]++; for(i=1;i<m;i++) ws[i]+=ws[i-1]; for(i=n-1;i>=0;i--) sa[--ws[x[i]]]=i; for(j=1,p=1;p<n;j*=2,m=p) { for(p=0,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<n;i++) wv[i]=x[y[i]]; for(i=0;i<m;i++) ws[i]=0; for(i=0;i<n;i++) ws[wv[i]]++; for(i=1;i<m;i++) ws[i]+=ws[i-1]; for(i=n-1;i>=0;i--) sa[--ws[wv[i]]]=y[i]; for(t=x,x=y,y=t,p=1,x[sa[0]]=0,i=1;i<n;i++) x[sa[i]]=cmp(y,sa[i-1],sa[i],j)?p-1:p++; //printf("p = %d\n", p ); } } void calheight(int *r,int *sa,int n){ // memset(height,0,sizeof(height)); // memset(rank,0,sizeof(rank)); int i,j,k=0; for(i=1;i<=n;i++) rank[sa[i]]=i; for(i=0;i<n; height[rank[i++]] = k ) for(k?k--:0,j=sa[rank[i]-1]; r[i+k]==r[j+k]; k++); } int data ,loc ,sa ; int n,q,id,start; char str[205]; bool vis[4005]; bool Judge (int x) { int i,j; bool flag=false; for (i=1;i<=n;i++) { int cnt=0; int L=i; while (L<=n && height[L]<x) L++; if (L>n) break; int R=L; while (R<=n && height[R]>=x) R++; memset(vis,false,sizeof(vis)); for (j=L-1;j<=R-1;j++) if (loc[sa[j]]!=-1) vis[loc[sa[j]]]=true; for (j=1;j<=q;j++) if (vis[j]) cnt++; if (cnt==q) { start=sa[L-1]; return true; } i=R; } return false; } void Input () { int i,de=170;//分隔符 n=0; memset(data,0,sizeof(data)); for (int id=1;id<=q;id++) { scanf("%s",str); int len=strlen(str); for (i=0;i<len;i++) { loc =id; data[n++]=(int)str[i]; } loc =-1; data[n++]=de++; //注意分隔符需变化 } data =0; DA(data,sa,n+1,++de); //分隔符可能很大 calheight(data,sa,n); } int main () { #ifdef ONLINE_JUDGE #else freopen("read.txt","r",stdin); #endif while (~scanf("%d",&q),q) { Input (); int low=0,high=n,mid,res=0; while (low<high) { mid = (low+high)>>1; if (Judge(mid)) res=mid,low=mid+1; else high=mid; } if (res==0) printf("IDENTITY LOST\n"); else { int k=start; for (int j=0;j<res;j++) //res子串长度 printf("%c",(char)data[k+j]); printf("\n"); } } return 0; }
相关文章推荐
- POJ 2774 Long Long Message+Hdu 1403 Longest Common Substring (后缀数组 最长公共子串)
- poj 3450/poj 3080 多串最长公共子串 后缀数组
- hdu1403 && poj 2774 最长公共子串 后缀数组
- POJ 2774 long long message(后缀数组求最长公共子串)
- POJ 2774 Long Long Message 后缀数组求最长公共子串
- poj 2774 最长公共子串(后缀数组)
- POJ 2774 (最长公共子串)后缀数组+二分
- poj 3450 Corporate Identity【后缀数组,求多个串的最长公共子串】
- 后缀数组之最长公共子串 poj 2774
- hdu 1403 Longest Common Substring 后缀数组求最长公共子串
- HDU 1403 Longest Common Substring(后缀数组,最长公共子串)
- POJ 2774 Long Long Message(后缀数组[最长公共子串])
- poj 2774 Long Long Message,后缀数组,求最长公共子串 hdu1403
- hdu 1403 Longest Common Substring 后缀数组求最长公共子串
- poj 2774 最长公共子串 后缀数组
- HDU 1403 Longest Common Substring(后缀数组 最长公共子串)
- POJ 2774 后缀数组:求最长公共子串
- poj 2774 最长公共子串 后缀数组
- POJ - 2774 Long Long Message (最长公共子串 后缀数组)
- HDU1403(后缀数组--最长公共子串)