http://poj.org/problem?id=3294
Life Forms
Time Limit: 5000MS |
|
Memory Limit: 65536K |
Total Submissions: 9931 |
|
Accepted: 2739 |
Description
wondered why most extraterrestrial life forms resemble humans, differing by superficial traits such as height , colour, wrinkles, ears, eyebrows and the like. A few bear no human resemblance; These typically has geometric or amorphous shapes like cubes, oil slicks or clouds of dust.
The answer is given in the 146th episode of Star trek-the Next Generation, titled The Chase. It turns out this in the vast majority of the quadrant's life forms ended up with a large fragment of common DNA.
Given the DNA sequences of several life forms represented as strings of letters, you is to find the longest substring tha T is shared by more than half of them.
Input
Standard input contains several test cases. Each test case is begins with 1≤ n ≤100 and the number of life forms. n lines follow; Each contains a string of lower case letters representing the DNA sequence of a life form. Each of the DNA sequence contains at least one and is more than-letters. A line containing 0 follows the last test case.
Output
For each test case, output the longest string or strings gkfx by more than half of the life forms. If There is many, output all of the them in alphabetical order. If There is no solution with at least one letter, output "?". Leave a empty line between test cases.
Sample Input
3abcdefgbcdefghcdefghi3xxxyyyzzz0
Sample Output
Bcdefgcdefgh?
Source
Waterloo Local Contest, 2006.9.30
Test instructions: A string of the largest length, which appears in more than half of the given string, has multiple output in dictionary order.
Idea: Use a different delimiter to spell the given string together. Then we split the answer, scan the height array, to determine whether the length of the string is more than half a row of continuous occurrence, note that this is not a continuous n/2 in a continuous height array, but belong to the n/2 of different given string, so you can begin to preprocess each suffix belongs to which string. The final output and judgment, according to the dictionary order because it is scanned height array is guaranteed.
Re a lot of hair, found that this is the problem, in the separation of strings, s[n]= ' z ' +i,a[n]=s[n]-' a ' +i+1, so write a problem 233,a[n] assigned ' z '-' a ' +1+i just fine.
POJ uses set to determine the timeout.
/** * @author neko01 *///#pragma comment (linker, "/stack:102400000,102400000") #include <cstdio> #include < cstring> #include <string.h> #include <iostream> #include <algorithm> #include <queue># Include <vector> #include <cmath> #include <set> #include <map>using namespace Std;typedef long Long LL; #define MIN3 (a,b,c) min (a,min (b,c)) #define MAX3 (A,B,C) max (A,max (b,c)) #define PB Push_back#define MP (A, b) make_ Pair (A, B) #define CLR (a) memset (a,0,sizeof a) #define CLR1 (a) memset (a,-1,sizeof a) #define DBG (a) printf ("%d\n", a) typedef pair<int,int> PP;CONST Double Eps=1e-9;const double Pi=acos ( -1.0); const int N=101005;int sa[n]; The number of the row is which suffix//sa[1~n] is a valid value, Sa[0] must be n is an invalid value int rank[n]; Rank suffix i row//rank[0~n-1] is valid value, Rank[n] must be 0 invalid value int height[n]; Sa[i] and Sa[i-1] The longest common prefix//height[2~n] is a valid value int t1[n],t2[n],c[n];void build_sa (int s[],int n,int m) {int *x=t1,*y=t2; First round count sort for (int i=0;i<m;i++) c[i]=0; for (int i=0;i<n;i++) c[x[i]=s[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 j=1;j<=n;j<<=1) {int p=0; Use the SA array directly to sort the second keyword for (int i=n-j;i<n;i++) y[p++]=i; for (int i=0;i<n;i++) if (sa[i]>=j) y[p++]=sa[i]-j; Count sort first keyword for (int i=0;i<m;i++) c[i]=0; for (int i=0;i<n;i++) c[x[y[i]]]++; for (int i=1;i<m;i++) c[i]+=c[i-1]; for (int i=n-1;i>=0;i--) sa[--c[x[y[i]]]]=y[i]; Calculates a new x array of swaps based on the SA and X arrays; 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]+j]==y[sa[i]+j]?p-1:p++; if (p>=n) break; M=p; }}void getheight (int s[],int n) {int k=0; for (int i=0;i<=n;i++) rank[sa[i]]=i; for (int i=0;i<n;i++) {if (k) k--; int j=sa[rank[i]-1]; while (S[i+k]==s[j+k]) k++; Height[rank[i]]=k; }}int Id[n];char s[n],str[n];int A[n];bool vis[105]; bool Gao (int n,int x,int m,int flag) {//set<int>st; St.insert (id[sa[1]); CLR (VIS); int sz=0; Vis[id[sa[1]]]=true; sz++; for (int. i=2;i<=n;i++) {while (i<=n&&height[i]>=x)//st.insert (Id[sa[i]]), i++; {if (!vis[id[sa[i]]) {vis[id[sa[i]]]=true; sz++; } i++; }//if (St.size () >M/2) if (SZ>M/2) {if (flag==0) return true; for (int j=0;j<x;j++) printf ("%c", S[sa[i-1]+j]); Puts (""); }//st.clear (); St.insert (Id[sa[i]); CLR (VIS); Vis[id[sa[i]]]=true; Sz=1; } return false;} int main () {int t,flag=1; while (~SCANF ("%d", &t) &&t) {int n=0; if (!flag) puts (""); flag=0; for (int i=1;i<=t;i++) {scanf ("%s", str); int Len=strlen (str); for (int j=0;j< len;j++) {s[n]=str[j]; a[n]=str[j]-' a ' +1; Id[n++]=i; } s[n]= ' Z ' +i; A[n]= ' z '-' a ' +1+i; Id[n++]=i; } if (t==1) {printf ("%s\n\n", str); Continue } s[n]= ' n ', a[n]=0; Build_sa (a,n+1,30+t); GetHeight (A,n); int ans=-1,l=1,r=1000; while (l<=r) {int mid= (L+R) >>1; if (Gao (n,mid,t,0)) ans=mid,l=mid+1; else r=mid-1; } if (Ans==-1) puts ("?"); Else Gao (n,ans,t,1); } return 0;}
poj3294 UVA 11107 life Forms suffix Array