bzoj1692 隊列變幻 貪心+尾碼數組 __尾碼數組

來源:互聯網
上載者:User
Description

FJ打算帶他的N(1 <= N <= 30,000)頭奶牛去參加一年一度的“全美農場主大獎賽”。在這場比賽中,每個參賽者都必須讓他的奶牛排成一列,然後領她們從裁判席前依次走過。 今年,競賽委員會在接受隊伍報名時,採用了一種新的登記規則:他們把所有隊伍中奶牛名字的首字母取出,按它們對應奶牛在隊伍中的次序排成一列(比如說,如果FJ帶去的奶牛依次為Bessie、Sylvia、Dora,登記人員就把這支隊伍登記為BSD)。登記結束後,組委會將所有隊伍的登記名稱按字典序升序排列,就得到了他們的出場順序。 FJ最近有一大堆事情,因此他不打算在這個比賽上浪費過多的時間,也就是說,他想儘可能早地出場。於是,他打算把奶牛們預先設計好的隊型重新調整一下。 FJ的調整方法是這樣的:每次,他在原來隊列的首端或是尾端牽出一頭奶牛,把她安排到新隊列的尾部,然後對剩餘的奶牛隊列重複以上的操作,直到所有奶牛都被插到了新的隊列裡。這樣得到的隊列,就是FJ拉去登記的最終的奶牛隊列。 接下來的事情就交給你了:對於給定的奶牛們的初始位置,計算出按照FJ的調整規則所可能得到的字典序最小的隊列。 Input

* 第1行: 一個整數:N

* 第2..N+1行: 第i+1行僅有1個'A'..'Z'中的字母,表示隊列中從前往後數第i 頭奶牛名字的首字母 Output

* 第1..??行: 輸出FJ所能得到的字典序最小的隊列。每行(除了最後一行)輸 出恰好80個'A'..'Z'中的字母,表示新隊列中每頭奶牛姓名的首 字母 Sample Input 6
A
C
D
B
C
B

輸入說明:

FJ有6頭順次排好隊的奶牛:ACDBCB

Sample Output ABCBCD

輸出說明:

運算元 原隊列 新隊列
#1 ACDBCB
#2 CDBCB A
#3 CDBC AB
#4 CDB ABC
#5 CD ABCB
#6 D ABCBC
#7 ABCBCD
題解: 首先如果左右單詞不一樣肯定是選字典序小的加入. 如果一樣的話可以比較以左邊字元開頭的尾碼和以右邊字元開頭的首碼。  所以把模板串反過來接到後面,中間加入一個分隔字元.建立尾碼數組. 然後首碼就可以轉化成尾碼直接比較了. 代碼:

#include<iostream>#include<cstdio>#include<cstring>#define N 60010using namespace std;int s[N],c[N],t1[N],t2[N],sa[N],rank[N],n,m,temp;char ch;bool cmp(int *y,int p,int q,int k){  int a=(p+k>=n)?-1:y[p+k];  int b=(q+k>=n)?-1:y[q+k];  return a==b&&y[p]==y[q];}void build_sa(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]=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 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=1;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]]=cmp(y,sa[i],sa[i-1],k)?p-1:p++;    if (p>=n) break;    m=p;   } }int main(){  scanf("%d",&n);s[n]='$';  for(int i=0;i<n;i++){   scanf("%*c%c",&ch);   s[2*n-i]=s[i]=ch;  }  m=n;n=n+n+1;build_sa(2666);   for (int i=0;i<n;i++) rank[sa[i]]=i;  //for (int i=0;i<n;i++) cout<<sa[i]<<' ';  int l=0,r=m-1;  while (l<r){    int a=rank[l],b=rank[m+m-r];    //cout<<l<<' '<<r<<' '<<a<<' '<<b<<' ';    if (a<b){      printf("%c",s[l]);l++;    }    else{      printf("%c",s[r]);r--;    }    temp++;    if (temp>=80&&(l!=r)){puts("");temp=0;}  }  printf("%c",s[l]);} 


聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.