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);
}

posted on 2011-03-15 10:43  宇宙吾心  阅读(412)  评论(0)    收藏  举报

导航