1. 程式人生 > >組委會正在為美團點評CodeM大賽的決賽設計新賽制

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

通過 隨機 space 個數字 數字 範圍 class 包括 bound



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

現在請問,參賽者小美最多可以活到第幾輪(初始為第0輪)?

輸入描述:
第一行一個整數 n (1≤n≤ 2^20),表示參加比賽的總人數。
接下來 n 個數字(數字範圍:-1000000…1000000),表示每個參賽者的積分。
小美是第一個參賽者。
輸出描述:
小美最多參賽的輪次。
輸入例子:
4
4 1 2 3
輸出例子:
2


模擬一下比賽過程即可:

我的思路是,盡量讓小美和比她分數低(包括相同,因為相同時是隨機比賽結果,且要求能通過的最大比賽場次)的選手去比賽,那麽首先想到排序,再求出小美分數在排序數組中的上界,計算出比小美分數高的選手數量r,然後就是模擬比賽的過程。

將選手劃分為兩個陣營(l:分數<=小美的選手,包括小美; r: 分數>小美的選手)。

規則是:在一輪比賽中,如果r為奇數,需要在l個中,抽一個(比小美分數小的)給r才能比賽,

      如果l==1,即只剩小美一個人了,那這局肯定是輸的,不計算在內,這時可能r中可能還有選手,但小美只能到這了。

      如果l>1,那這一輪比賽分別在l-1個選手, 與r+1個選手, 兩個陣營內進行。小美在l陣營中,肯定會贏。勝利次數+1。

    在一輪比賽中,如果r 為0,小美一直比下去。

代碼:

#include <iostream>
#include <vector>
#include <algorithm>

using namespace std;

int main()
{
    int n;
    cin >> n;
    vector<int> a;
    int data;
    for( int i = 0
; i < n; i++ ) { cin >> data; a.push_back( data ); } data = a[0]; sort( a.begin(), a.end() ); int r = a.end() - upper_bound( a.begin(), a.end(), data ); //cout << "r is: " << r << endl; int l = n - r; int cnt = 0; if( r == 0 ) { cnt += ( l / 2 ); } while( r > 0 && l > 1 ) { if( r & 1 ) { r++; l--; } cnt++; r /= 2; l /= 2; } cout << cnt << endl; return 0; }

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