zoukankan      html  css  js  c++  java
  • 【poj3623】 Best Cow Line, Gold

    http://poj.org/problem?id=3623 (题目链接)

    题意

      给出一个字符串,每次可以取首或尾接到一个新的字符串后面,求构出的字典序最小的新字符串。

    Solution

      首先可以发现,一定是优先选择字典序最小的,所以就将字符串反过来接在后面并用分隔符隔开,求一遍后缀数组,然后每次比较首和尾的rank,取rank靠前的记入答案即可。

    细节

      每80个字母一行→_→

    代码

    // poj3623
    #include<algorithm>
    #include<iostream>
    #include<cstdlib>
    #include<cstring>
    #include<cstdio>
    #include<cmath>
    #include<ctime>
    #define LL long long
    #define inf 1<<30
    #define Pi acos(-1.0)
    #define free(a) freopen(a".in","r",stdin),freopen(a".out","w",stdout);
    using namespace std;
    
    const int maxn=300010;
    int sa[maxn],height[maxn],rank[maxn],n;
    char s[maxn],ch[maxn/10][20],ans[maxn];
    
    namespace Suffix {
    	int wa[maxn],wb[maxn],ww[maxn];
    	bool cmp(int *r,int a,int b,int l) {
    		return r[a]==r[b] && r[a+l]==r[b+l];
    	}
    	void da(char *r,int *sa,int n,int m) {
    		int i,j,p,*x=wa,*y=wb;
    		for (i=0;i<=m;i++) ww[i]=0;
    		for (i=1;i<=n;i++) ww[x[i]=r[i]]++;
    		for (i=1;i<=m;i++) ww[i]+=ww[i-1];
    		for (i=n;i>=1;i--) sa[ww[x[i]]--]=i;
    		for (p=0,j=1;p<n;j*=2,m=p) {
    			for (p=0,i=n-j+1;i<=n;i++) y[++p]=i;
    			for (i=1;i<=n;i++) if (sa[i]>j) y[++p]=sa[i]-j;
    			for (i=0;i<=m;i++) ww[i]=0;
    			for (i=1;i<=n;i++) ww[x[y[i]]]++;
    			for (i=1;i<=m;i++) ww[i]+=ww[i-1];
    			for (i=n;i>=1;i--) sa[ww[x[y[i]]]--]=y[i];
    			for (swap(x,y),p=x[sa[1]]=1,i=2;i<=n;i++)
    				x[sa[i]]=cmp(y,sa[i-1],sa[i],j) ? p : ++p;
    		}
    	}
    	void calheight(char *r,int *sa,int n) {
    		for (int i=1;i<=n;i++) rank[sa[i]]=i;
    		for (int k=0,i=1;i<=n;i++) {
    			if (k) k--;
    			int j=sa[rank[i]-1];
    			while (r[i+k]==r[j+k]) k++;
    			height[rank[i]]=k;
    		}
    	}
    }
    
    int main() {
    	scanf("%d",&n);
    	char ch[10];
    	for (int i=1;i<=n;i++) {
    		scanf("%s",ch);s[i]=ch[0];
    	}
    	s[n+1]='#';
    	int len=n;
    	for (int i=1;i<=n;i++) s[n+i+1]=s[n-i+1];
    	n=n+n+1;
    	Suffix::da(s,sa,n,300);
    	Suffix::calheight(s,sa,n);
    	int tot=0,l=1,r=len;
    	while (tot<len) {
    		int x=rank[l],y=rank[len-r+1+len+1];
    		if (x<y) ans[++tot]=s[l++];
    		else ans[++tot]=s[r--];
    	}
    	for (int i=1;i<=tot;i++) {
    		printf("%c",ans[i]);
    		if (i%80==0) puts("");
    	}
        return 0;
    }
    
  • 相关阅读:
    POJ2286 The Rotation Game
    jQuery火箭图标返回顶部代码
    jQuery火箭图标返回顶部代码
    jQuery火箭图标返回顶部代码
    jQuery火箭图标返回顶部代码
    jQuery火箭图标返回顶部代码
    jQuery火箭图标返回顶部代码
    jQuery火箭图标返回顶部代码
    jQuery火箭图标返回顶部代码
    jQuery火箭图标返回顶部代码
  • 原文地址:https://www.cnblogs.com/MashiroSky/p/6283986.html
Copyright © 2011-2022 走看看