1. 程式人生 > >4567 Brilliant Programmers Show 2013長沙邀請賽

4567 Brilliant Programmers Show 2013長沙邀請賽

寫在前面:這道題題目資料有問題,第40組以後的資料沒有任何輸出,也不知道是哪位大神發現的,反正就是這樣...

題意:有一隊人,相鄰的兩個人中排名靠後的可以向排名靠前的挑戰,如果挑戰成功,他們排名互換,現在已知初始各排名的人發起挑戰的次數,問你是否合理,如果合理能否確定冠軍

分析:首先對於在每個位置的人來說,實際挑戰次數記為t[i],他們都有一個最大可能的挑戰次數,我們記為m[i],其中包括在他前面的人的挑戰次數a[i],其中a[i]=a[i-1]+t[i]+1,和在他後面的人的挑戰次數b[i],既然是最大的挑戰次數,那麼所有的人必定和他輪番交戰,儘量拖延次數,所以如果t[i]==m[i],那麼他就是冠軍,如果t[i]>m[i],那麼這是不合理的,如果每個人的t[i]<m[i],冠軍是不確定的,但是如果每個人都去判斷的話時間為O(n^2),超過了要求,所以根據題意我們選擇最後一個t[i]>=a[i]的人序號為k,證明如下:t[i]<a[i]的人,t[i]一定小於m[i],不考慮,t[i]>=a[i]但序號h<k,則k一個人就可以去和h相互輪換直至結束,所以只要考慮最後一個數k即可。

程式碼:

#include <bits/stdc++.h>

using namespace std;

int n,ca,flag,t;
long long a[1000005],sum[1000005],t1,t2;

int main()
{
    ios::sync_with_stdio(false);
    ca=0;
    while(cin>>n)
    {
        ca++;
        sum[0]=0;
        for(int i=1;i<=n;i++)
        {
            cin>>a[i];
            sum[i]=a[i]+sum[i-1]+1;
        }
        if(ca>=40)
            continue;
        t=0;
        for(int i=1;i<=n;i++)
            if(a[i]>=sum[i-1])
                t=i;
        t1=t2=0;
        for(int i=t+1;i<=n;i++)
        {
            if(a[i]<=t1)
                t1++;
            else
                t2+=a[i]-t1;
        }
        if(a[t]>sum[t-1]+t2)
            cout<<"Bad Rescue"<<endl;
        else if(a[t]==sum[t-1]+t2)
            cout<<t<<endl;
        else
            cout<<"Unknown"<<endl;
    }
    return 0;
}