1. 程式人生 > >美團CodeM資格賽第二題

美團CodeM資格賽第二題

不同的 一位 決勝 由於 col logs top scanf sub

錦標賽

時間限制:1秒

空間限制:32768K

組委會正在為美團點評CodeM大賽的決賽設計新賽制。

比賽有 n 個人參加(其中 n 為2的冪),每個參賽者根據資格賽和預賽、復賽的成績,會有不同的積分。比賽采取錦標賽賽制,分輪次進行,設某一輪有 m 個人參加,那麽參賽者會被分為 m/2 組,每組恰好 2 人,m/2 組的人分別廝殺。我們假定積分高的人肯定獲勝,若積分一樣,則隨機產生獲勝者。獲勝者獲得參加下一輪的資格,輸的人被淘汰。重復這個過程,直至決出冠軍。

現在請問,參賽者小美最多可以活到第幾輪(初始為第0輪)?
輸入描述:
第一行一個整數 n (1≤n≤ 2^20),表示參加比賽的總人數。
接下來 n 個數字(數字範圍:-1000000…1000000),表示每個參賽者的積分。
小美是第一個參賽者。


輸出描述:
小美最多參賽的輪次。

輸入例子:
4
4 1 2 3

輸出例子:
2


由於是讓第一位選手存活最長時間
所以我們可以只關心積分小於等於這位選手的選手
而這些積分小於等於它的選手,每輪結束剩下多少呢?沒錯是k/2
k是2的冪次,顯然我們讓內部決勝負,能剩下k/2個比第一位選手分數少的選手
k不是2的冪次,顯然我們還是讓內部決勝負最佳,因為如果每個人對陣分數高的外部選手,可以讓第一位選手提前結束
觀察得其答案也為k/2
綜合一下,每輪剩下的人數就是k/2(比第一位選手小的
但每次/2是不對的,假如我們考慮 2 1 1 3 4 5 6 7
僅考慮 1 1,按照我們的邏輯,這個1,1可以用兩次
但其實如果1,1內部決勝負,2就必須和其他比他大的比
那麽第一輪就GG,所以,前提是首先從小於等於它的選手中挑一個和他比,首先保證其存活
然後讓剩下的k個人內部決勝負
 1 #include <stdio.h>
 2 #include <algorithm>
 3 using namespace std;
 4 int a[1123456];
 5 int main(){
 6     int n;scanf("%d",&n);
 7     for(int i=1;i<=n;++i){
 8         scanf("%d",a+i);
 9     }
10     int x=a[1],small=0;
11     for(int i=2;i<=n;++i){
12         if(a[i]<=x) small++;
13 } 14 int ans=0; 15 while(n!=1){ 16 if(small==0) break; 17 small--;//首先保證自身存活 18 small>>=1; 19 ans++; 20 n>>=1; 21 } 22 printf("%d\n",ans); 23 return 0; 24 }

美團CodeM資格賽第二題