Usaco 2007 Dec gold 隊列變換

隊列變換 

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

Sample Output

ABCBCD

Data Constraint

Hint

【樣例解釋】
操作數 原隊列 新隊列
#1 ACDBCB  
#2 CDBCB A
#3 CDBC AB
#4 CDB ABC
#5 CD ABCB
#6 D ABCBC
#7   ABCBCD

題解:

貪心,頭尾指針枚舉字符串兩邊,選小的那個,若相等,則往內延伸判斷哪邊裏面的字符更小


參考程序:

var     n,l,r,i,t1,t2,bz:longint;
        s,s2:ansistring;
        c:char;
begin
        readln(n);
        for i:=1 to n do
        begin
                readln(c);
                s:=s+c;
                if (i>1)and(s[i]<>s[i-1]) then bz:=1;
        end;
        if bz=0 then
        begin
                for i:=1 to length(s) do
                begin
                        write(s[i]);
                        if i mod 80=0 then writeln;
                end;
                exit;
        end;
        l:=1;
        r:=length(s);
        while l<r do
        begin
                if s[l]<s[r] then
                begin
                        s2:=s2+s[l];
                        inc(l);
                end else
                if s[r]<s[l] then
                begin
                        s2:=s2+s[r];
                        dec(r);
                end else
                begin
                        t1:=l;
                        t2:=r;
                        while s[t1]=s[t2] do
                        begin
                                inc(t1);
                                dec(t2);
                        end;
                        if s[t1]<s[t2] then
                        begin
                                s2:=s2+s[l];
                                inc(l);
                        end else
                        begin
                                s2:=s2+s[r];
                                dec(r);
                        end;
                end;
        end;
        s2:=s2+s[l];
        for i:=1 to length(s2) do
        begin
                write(s2[i]);
                if i mod 80=0 then writeln;
        end;
end.



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章