比賽有 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; }