4567 Brilliant Programmers Show 2013長沙邀請賽
阿新 • • 發佈:2019-02-15
寫在前面:這道題題目資料有問題,第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; }