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



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

如今請問,參賽者小美最多能夠活到第幾輪(初始爲第0輪)?ios

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


模擬一下比勝過程便可:數組

個人思路是,儘可能讓小美和比她分數低(包括相同,由於相同時是隨機比賽結果,且要求能經過的最大比賽場次)的選手去比賽,那麼首先想到排序,再求出小美分數在排序數組中的上界,計算出比小美分數高的選手數量r,而後就是模擬比賽的過程。spa

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

規則是:在一輪比賽中,若是r爲奇數,須要在l箇中,抽一個(比小美分數小的)給r才能比賽,blog

      若是l==1,即只剩小美一我的了,那這局確定是輸的,不計算在內,這時可能r中可能還有選手,但小美只能到這了。排序

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

    在一輪比賽中,若是r 爲0,小美一直比下去。it

代碼:io

#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;
}

 

另外還有一種更簡單的思路:class

也是小美只須要和小於等於本身積分的選手(num個)比較便可,比較次數就是log2 num次。

#include <iostream>
#include <algorithm>
#include <cmath>

using namespace std;

int main()
{
    int n;
    cin >> n;
    int data, other, sum = 1;
    cin >> data;
    for( int i = 0; i < n; i++ )
    {
        cin >> other;
        if( other <= data )
        {
            sum++;
        }
    } 
    cout << (int)( log( sum ) / log( 2 ) ) << endl;
    return 0;
}
相關文章
相關標籤/搜索