題目:
n支隊伍比賽,分別編號為0,1,2。。。。n-1,已知它們之間的實力對比關係,儲存在一個二維數組w[n][n]中,w[i][j] 的值代表編號為i,j的隊伍中更強的一支 所以w[i][j]=i 或者j,現在給出它們的出場順序,並儲存在數組order[n]中。
比如order[n] = {4,3,5,8,1......},那麼第一輪比賽就是 4對3, 5對8。。。。。。
勝者晉級,敗者淘汰,同一輪淘汰的所有隊伍排名不再細分,即可以隨便排,
下一輪由上一輪的勝者按照順序,再依次兩兩比,比如可能是4對5,直至出現第一名
編程實現,給出二維數組w,一維數組order 和 用於輸出比賽名次的數組result[n],求出result
思路:
題目中已經明確說明了不需要求出每一個的名次,比賽方法也已經明確給出,因此在演算法的設計時就比較明確了,通過簡單的例子可以看出比賽過程有一個最多的比賽輪次:log2(n)+1輪。有點像是二叉樹的層數。演算法中使用了一個輔助的數組來標記下一輪的的名單,以下代碼基本上是按照這個思路來的,未仔細測試邊界條件
UINT32 w[n][n];//已知條件UINT32 order[n];//已知條件UINT32 result[n];//第i個元素對應了i的名次(應該是淘汰批次)UINT32 GetID(UINT32 list[n] , UINT32 startPos=0){//尋找第一個不為0的位置int i = startPos;for( ;i < n; i++){if( list[i] != 0){return i;}}return n;}UINT32* bisai(UINT32 w[n][n],UINT32 order[n]){UINT32 result[n];memset(result,n/2,sizeof(UINT32)*n);UINT32 nextID[n];//晉級名單memset(nextID,1,sizeof(UINT32)*n);UINT32 i,j;while(1){//比賽開始for( i = GetID(nextID), j = GetID(nextID,i) ; i < n&& j < n; i = GetID(nextID,j),j = GetID(nextID,i)){if( i == w[i][j] )//i晉級,j被淘汰{nextID[j] = 0;//j被淘汰--result[i];}if( j == w[i][j]){nextID[i] = 0;//i被淘汰--result[j];}}if( i == j){//i就是第一名了break;}}return result;}