Cpp環境【POJ3623】【Usaco2007Dec】【Vijos2993】Best Cow Line, Gold 最佳隊列[2]

POJ3623 Best Cow Line,Gold 原題

Description  問題描述

FJ is about to take his N (1 ≤ N ≤ 30,000) cows to the annual”Farmer of the Year” competition. In this contest every farmer arranges his cows in a line and herds them past the judges.
The contest organizers adopted a new registration scheme this year: simply register the initial letter of every cow in the order they will appear (i.e., If FJ takes Bessie, Sylvia, and Dora in that order he just registers BSD). After the registration phase ends, every group is judged in increasing lexicographic order according to the string of the initials of the cows’ names.
FJ is very busy this year and has to hurry back to his farm, so he wants to be judged as early as possible. He decides to rearrange his cows, who have already lined up, before registering them.
FJ marks a location for a new line of the competing cows. He then proceeds to marshal the cows from the old line to the new one by repeatedly sending either the first or last cow in the (remainder of the) original line to the end of the new line. When he’s finished, FJ takes his cows for registration in this new order.
Given the initial order of his cows, determine the least lexicographic string of initials he can make this way.


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

    Input  【輸入格式】
  • Line 1: A single integer: N
  • Lines 2..N+1: Line i+1 contains a single initial (‘A’..’Z’) of the cow in the ith position in the original line

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

Output  【輸出格式】

The least lexicographic string he can make. Every line (except perhaps the last one) contains the initials of 80 cows (‘A’..’Z’) in the new line.


  輸出FJ所能得到的字典序最小的隊列。每行(除了最後一行)輸出恰好80個’A’..’Z’中的字母,表示新隊列中每頭奶牛姓名的首字母。

Sample Input  【輸入樣例】

6
A
C
D
B
C
B

Sample Output  【輸出樣例】

ABCBCD

【思路梳理】

  典型的貪心問題,選擇目前最優;如果兩個選擇都是目前最優,那麼就選擇整體最優。每一次我們都夠選擇在隊尾的奶牛或者是在隊首的奶牛。因爲我們選擇的這頭奶牛將被放在新的隊列的尾部,所以我們應該選擇一個字典序較小的奶牛,即目前最優;當兩個奶牛同時是目前最優(字典序相同)我們就分別從隊首和隊尾向中間尋找兩頭字典序不同的奶牛。顯然這頭奶牛越靠近隊伍的哪一邊,我們就應該從哪一邊開始取奶牛。給出代碼如下:

【Cpp代碼】
#include<cstdio>
#include<cctype>
#define maxn 30005
using namespace std;
char ch[maxn],ans[maxn];
int n;

void read()
{
    char c=getchar();
    for(int i=1;i<=n;i++)
    {
        while(c<'A' || c>'Z')   c=getchar();
        ch[i]=c;
        c=getchar();
    }
}

void solve()
{
    int front=1,rear=n;
    int t=0;
    while(front<=rear)
    {
        if(ch[front]>ch[rear])  ans[++t]=ch[rear--];
        else if(ch[front]<ch[rear]) ans[++t]=ch[front++];
        else if(ch[front]==ch[rear])
        {
            int i=front,j=rear;
            while(i!=j && ch[i]==ch[j])
            {
                i++,j--;
            }
            if(ch[i]>ch[j]) ans[++t]=ch[rear--];
            else ans[++t]=ch[front++];
        }
    }

    int m=0;
    while(m!=n)
    {
        for(int i=1;i<=80;i++)if(m!=n)
            printf("%c",ans[++m]);
        printf("\n");
    }

}

int main()
{
    //freopen("in.txt","r",stdin);
    //freopen("out.txt","w",stdout);
    scanf("%d",&n);
    read();
    solve();
    //for(int i=1;i<=n;i++) printf("%c",ch[i]);
    return 0;
}
發佈了59 篇原創文章 · 獲贊 10 · 訪問量 3萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章