[URAL1517 Freedom of Choice]
2012-03-29 18:59
351 查看
[关键字]:后缀数组 字符串
[题目大意]:给定两个字符串A 和B,求最长公共子串。
//==============================================================================
[分析]:求两个字符串的最长公共子串实际上就是求两个字符串的两个后缀的最长公共前缀。所以把两个字符串连起来中间用一个没出现的字符(小于任何一个原字符串中的字符)连起来,最后再加上一个字符(小于任何一个字符)。然后求这个新串中的最长公共前缀,依次枚举每个i求出符合sa[i-1]在一串,sa[i]在二串的所有height的最大值。
[代码]:
View Code
[题目大意]:给定两个字符串A 和B,求最长公共子串。
//==============================================================================
[分析]:求两个字符串的最长公共子串实际上就是求两个字符串的两个后缀的最长公共前缀。所以把两个字符串连起来中间用一个没出现的字符(小于任何一个原字符串中的字符)连起来,最后再加上一个字符(小于任何一个字符)。然后求这个新串中的最长公共前缀,依次枚举每个i求出符合sa[i-1]在一串,sa[i]在二串的所有height的最大值。
[代码]:
View Code
#include<iostream> #include<cstdio> #include<cstdlib> #include<cstring> #include<algorithm> using namespace std; const int MAXN=200010; const int MAXL=200010; int n,n1,n2; int top[MAXN],sa[MAXN],r[MAXN*2],temp[MAXN],height[MAXN]; char s[MAXL],s1[MAXL],s2[MAXL],ch; void Init() { scanf("%d",&n); scanf("%c",&ch); gets(s1); gets(s2); n1=strlen(s1); for (int i=0;i<n1;++i) s[i]=s1[i]; s[n1]='$'; n2=strlen(s2); for (int i=0;i<n2;++i) s[n1+1+i]=s2[i]; n=n1+n2+1; s[n++]='#'; } void Make() { int i,j,len,m; memset(top,0,sizeof(top)); m=n<256?256:n; for (i=0;i<n;++i) ++top[r[i]=s[i]&0xff]; for (i=1;i<m;++i) top[i]+=top[i-1]; for (i=0;i<n;++i) sa[--top[r[i]]]=i; for (len=1;len<n;len<<=1) { for (i=0;i<n;++i) { j=sa[i]-len; if (j<0) j+=n; temp[top[r[j]]++]=j; } sa[temp[top[0]=0]]=j=0; for (i=1;i<n;++i) { if (r[temp[i]]!=r[temp[i-1]] || r[temp[i]+len]!=r[temp[i-1]+len]) top[++j]=i; sa[temp[i]]=j; } memcpy(r,sa,sizeof(sa)); memcpy(sa,temp,sizeof(sa)); if (j>=n-1) break; } } void Lcp() { int i,j,k; for (j=r[height[i=k=0]=0];i<n-1;++i,++k) while (k>=0 && s[i]!=s[sa[j-1]+k]) height[j]=k--,j=r[sa[j]+1]; } void Solve() { // for (int i=0;i<=n;++i) printf("%d ",height[i]); // printf("\n"); int MAX=0,MAXJ; for (int i=3;i<n;++i) if ((sa[i]<n1 && sa[i-1]>n1) || (sa[i]>n1 && sa[i-1]<n1)) if (MAX<height[i]) MAX=height[i],MAXJ=sa[i]; //printf("%d\n",MAX); for (int i=MAXJ;i<MAXJ+MAX;++i) printf("%c",s[i]); printf("\n"); } int main() { freopen("in.txt","r",stdin); freopen("out.txt","w",stdout); Init(); //printf("%d %s\n",n,s); Make(); Lcp(); Solve(); return 0; }
相关文章推荐
- URAL 1517 Freedom of Choice 后缀数组
- Ural1517 Freedom of choice, 后缀数组,最长公共子串
- Freedom of Choice URAL - 1517
- URAL 1517 Freedom of Choice 后缀数组 入门
- URAL1517-Freedom of Choice
- URAL 1517 Freedom of Choice
- URAL 1517 Freedom of Choice
- URAL 1517 Freedom of Choice
- URAL 1517 Freedom of Choice (后缀数组 输出两个串最长公共子串)
- URAL 1517 Freedom of Choice
- POJ 2774 & URAL 1517(最长公共子串)
- URAL 1517. Freedom of choice(后缀数组:最长公共连续子串)
- 后缀数组poj2774(hdu1403)ural1517
- URAL 1517 Freedom of Choice(后缀数组,最长公共字串)
- POJ 2774 Long Long Message && URAL 1517. Freedom of Choice(求最长重复子序列)
- URAL 1517 后缀数据+最长公共前缀LCP
- URAL 题目1517. Freedom of Choice(后缀数组,求公共最长串)
- Ural 1517 最长公共子序列
- ural 1517
- URAL 1517. Freedom of choice(后缀数组:最长公共连续子串)