poj 3294
后缀数组,height的考察。
代码:
#include<iostream>
#include<fstream>
using namespace std;
#define N 100200
int sa[N],sa1[N],rank[N],rank1[N],c[N],h[N];
int m[N];
int n,pow,count;
int cmp(const void *a,const void *b){
int x=*(int*)a;
int y=*(int*)b;
if(rank[x]!=rank[y])
return(1);
else
if(rank[x+pow]!=rank[y+pow])
return(1);
else
return(0);
}
int cmp1(const void *a,const void *b){
return m[*((int *)a)]-m[*((int *)b)];
}
void creat(){
int i,j,k;
for(i=0;i<n;i++)
sa[i]=i;
qsort(sa,n,sizeof(int),cmp1);
for(i=0,j=0;i<n;i++)
{
if(i>0&&m[sa[i]]!=m[sa[i-1]])
j++;
rank[sa[i]]=j;
}
for(pow=1;pow<n;pow*=2)
{
for(i=0;i<n;i++)
c[i]=0;
for(i=0;i<n;i++)
if(sa[i]+pow<n)
c[rank[sa[i]+pow]]++;
else
c[rank[sa[i]]]++;
for(i=1;i<n;i++)
c[i]+=c[i-1];
for(i=n-1;i>=0;i--)
if(sa[i]+pow<n)
sa1[--c[rank[sa[i]+pow]]]=sa[i];
else
sa1[--c[rank[sa[i]]]]=sa[i];
for(i=0;i<n;i++)
c[i]=0;
for(i=0;i<n;i++)
c[rank[sa1[i]]]++;
for(i=1;i<n;i++)
c[i]+=c[i-1];
for(i=n-1;i>=0;i--)
sa[--c[rank[sa1[i]]]]=sa1[i];
for(i=0,j=0;i<n;i++)
{
if(i>0&&cmp(&sa[i],&sa[i-1])!=0)
j++;
rank1[sa[i]]=j;
}
for(i=0;i<n;i++)
rank[i]=rank1[i];
}
}
void height(){
int i,j,k=0;
for(i=0;i<n;i++)
{
if(rank[i]==0)
h[rank[i]]=k=0;
else
{
if(k>0) k--;
j=sa[rank[i]-1];
for(;m[i+k]==m[j+k];k++);
h[rank[i]]=k;
}
}
}
int v[101];
int f[100201];
int judge(int len){
int i;
int sum=0;
memset(v,0,sizeof(v));
for(i=1;i<n;i++)
{
if(h[i]>=len)
{
if(f[sa[i-1]]!=0&&v[f[sa[i-1]]]==0)
{
sum++;
if(sum>count/2) return 1;
v[f[sa[i-1]]]=1;
}
if(f[sa[i]]!=0&&v[f[sa[i]]]==0)
{
sum++;
if(sum>count/2) return 1;
v[f[sa[i]]]=1;
}
}
else
{
memset(v,0,sizeof(v));
sum=0;
}
}
return(0);
}
void print(int len){
int i,j;
int sum=0;
int find=0;
memset(v,0,sizeof(v));
for(i=1;i<n;i++)
{
if(h[i]>=len&&!find)
{
if(f[sa[i-1]]!=0&&v[f[sa[i-1]]]==0)
{
sum++;
if(sum>count/2)
{
find=1;
for(j=sa[i-1];j<sa[i-1]+len;j++)
cout<<(char)(m[j]-100);
cout<<endl;
}
v[f[sa[i-1]]]=1;
}
if(f[sa[i]]!=0&&v[f[sa[i]]]==0&&!find)
{
sum++;
if(sum>count/2) {
find=1;
for(j=sa[i];j<sa[i]+len;j++)
cout<<(char)(m[j]-100);
cout<<endl;
}
v[f[sa[i]]]=1;
}
}
if(h[i]<len)
{
memset(v,0,sizeof(v));
sum=0;
find=0;
}
}
}
int main(){
int i,j,k,mid;
// ifstream cin("in.txt");
char c[1005];
while(1)
{
// cin>>count;
scanf("%d",&count);
if(count==1)
{
// cin>>c;
scanf("%s",c);
cout<<c<<endl<<endl;
continue;
}
if(count==0) return 0;
n=0;
for(i=1;i<=count;i++)
{
// cin>>c;
scanf("%s",c);
for(j=0;j<strlen(c);j++)
{
m[n++]=c[j]+100;
f[n-1]=i;
}
m[n++]=count-i+1;
f[n-1]=0;
}
creat();
height();
i=0;j=n;
while(i<=j)
{
mid=(i+j)/2;
if(judge(mid)) i=mid+1;
else
j=mid-1;
}
if(j==0) cout<<'?'<<endl<<endl;
else
{
print(j);
cout<<endl;
}
}
return(0);
}
浙公网安备 33010602011771号