Main topic:
Find the longest and smallest common substring in these DNA sequences.
Thinking Analysis:
The length of the answer, go to the height of the scan whether this length is satisfied, once satisfied on the output immediately. This will ensure that the dictionary order is minimized.
#include <cstdio> #include <iostream> #include <cstring> #include <algorithm> #define MAXN 1005using namespace Std;char str[maxn];int sa[maxn],t1[maxn],t2[maxn],c[maxn],n;void suffix (int m) {int *x=t1,*y=t2; for (int i=0;i<m;i++) c[i]=0; for (int i=0;i<n;i++) c[x[i]=str[i]]++; for (int i=1;i<m;i++) c[i]+=c[i-1]; for (int i=n-1;i>=0;i--) sa[--c[x[i]]]=i; for (int k=1;k<=n;k<<=1) {int p=0; for (int i=n-k;i<n;i++) y[p++]=i; for (int i=0;i<n;i++) if (sa[i]>=k) y[p++]=sa[i]-k; for (int i=0;i<m;i++) c[i]=0; for (int i=0;i<n;i++) c[x[y[i]]]++; for (int i=0;i<m;i++) c[i]+=c[i-1]; for (int i=n-1;i>=0;i--) sa[--c[x[y[i]]]]=y[i]; Swap (x, y); p=1;x[sa[0]]=0; for (int i=1;i<n;i++) x[sa[i]]=y[sa[i-1]]==y[sa[i]]&&y[sa[i-1]+k]==y[sa[i]+k]?p-1:p++; if (p>=n) break; M=p; }}int rank[maxn],height[maxn];void getheight () {int k=0; for (inti=0;i<n;i++) rank[sa[i]]=i; for (int i=0;i<n;i++) {if (k) k--; if (!rank[i]) continue; int j=sa[rank[i]-1]; while (Str[i+k]==str[j+k]) k++; Height[rank[i]]=k; }}int pos,n,fans;bool vis[20];int bel[maxn];bool ok () {for (int i=1;i<=n;i++) if (!vis[i]) return false; return true;} BOOL Check (int len) {pos=-1; memset (vis,false,sizeof Vis); int i; for (i=1;i<n;i++) {if (Height[i]<len) {if (ok ()) {pos=sa[i-1 ]; return true; } memset (vis,false,sizeof vis); } else {if (!vis[bel[sa[i-1]]) vis[bel[sa[i-1]]]=true; if (!vis[bel[sa[i]]]) vis[bel[sa[i]]]=true; if (ok ()) {pos=sa[i]; return true; }}} if (ok ()) pos=sa[i-1]; return pos!=-1;} Char Tmp[100];int main () {int T; scanf ("%d", &t); while (t--) {scanf ("%d", &n); int top=0; for (int i=1;i<=n;i++) {scanf ("%s", TMP); for (int j=0;j<60;j++) {bel[top]=i; STR[TOP++]=TMP[J]; } bel[top]=i; Str[top++]=127-i; } str[top-1]=0; N=top; suffix (128); GetHeight (); int l=3,r=60,mid,ans=0; while (l<=r) {mid= (l+r) >>1; if (check (mid)) ans=mid,fans=pos,l=mid+1; else r=mid-1; } if (ans<3) printf ("no significant commonalities"); else {for (int i=fans;i<fans+ans;i++) printf ("%c", Str[i]); } puts (""); } return 0;}
POJ 3080 Blue Jeans (suffix array)