36.引用自網友:longzuo(運算)
谷歌筆試:
19
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。
我用result先儲存每個隊伍晉級的輪次,利用vector後進先出的特點來輸出結果
/* 36.引用自網友:longzuo(運算) 谷歌筆試: 19 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。 */ #include <iostream> #include <vector> #include <string.h> using namespace std; //假設n一定是2的n次方,即每一輪不會出現輪空的情況 void getRank(int *w[], int * order, int * result, int n) { memset(result, 0, n * sizeof(int)); vector<int> stack; int round = 0; int n2 = n; while(n2 != 1) { n2 = (n2>>1); round++; } for(int r = 0; r < round; r++) //對比賽輪次迴圈 { int i = 0; int num = 0; int member[2] = {0}; while(i < n)//對比賽隊伍迴圈 { if(result[i] == r) { member[num++] = i; } if(num == 2) { if(*((int*)w + n * member[0] + member[1]) == member[0]) { result[member[0]]++; stack.push_back(member[1]); } else { result[member[1]]++; stack.push_back(member[0]); } num = 0; } i++; } } for(int i = 0; i < n; i++) //冠軍進棧 { if(result[i] == round) { stack.push_back(i); } } for(int i = 0; i < n; i++) { result[i] = stack.back(); stack.pop_back(); } } int main() { int w[4][4] = {{0, 0, 2, 0}, {0, 1, 1, 3}, {2, 1, 2, 3}, {0, 3, 3, 3}}; int order[4] ={1, 2, 3, 4}; int result[4]; getRank((int **)w, order, (int *)result, 4); return 0; }
我的實現不好,因為沒有考慮輪空的情況。網上有兩個我覺得還不錯的方法,都考慮了輪空,也很簡潔。
http://blog.csdn.net/yuucyf/article/details/6733226
利用了vector 的 earse 每次存名次的時候從 result的最後一個開始存就可以了。
/*---------------------------- Copyright by yuucyf. 2011.08.30 -----------------------------*/ #include "stdafx.h" #include <iostream> #include <vector> #include <assert.h> using namespace std; bool CalcPosition(int **ppW, int *pOrder, int *pResult, int nGroup) //nGroup arg mean n x n { assert(ppW); assert(pOrder); assert(pResult); assert(nGroup > 0); int i32I = 0, i32J = 0; int nCurPos = nGroup - 1; vector<int> vectOrder; for (i32I = 0; i32I < nGroup; i32I++) vectOrder.push_back(pOrder[i32I]); while (vectOrder.size() > 1) { for (vector<int>::iterator it = vectOrder.begin(); it != vectOrder.end(); ++it) { if (it + 1 != vectOrder.end()) { if (ppW[*it][*(it+1)] == *it) { pResult[nCurPos--] = *(it+1); vectOrder.erase(it+1); } else { pResult[nCurPos--] = *it; it = vectOrder.erase(it); } } } } if (vectOrder.size() == 1) pResult[nCurPos--] = vectOrder[0]; return true; } int _tmain(int argc, _TCHAR* argv[]) { int n; cout << "請輸入隊伍數"; cin >> n; cout << endl << "輸入實力對比關係" << endl; int **ppW = new int* [n]; assert(*ppW); for (int i32I = 0; i32I < n; i32I++) { ppW[i32I] = new int [n]; assert(ppW); for (int i32J = 0; i32J < n; i32J++) cin >> ppW[i32I][i32J]; } int *pOrder = new int[n]; assert(pOrder); cout << "請輸入出場順序" << endl; for (int i32I = 0; i32I < n; i32I++) cin >> pOrder[i32I]; int *pRes = new int[n]; assert(pRes); if (CalcPosition(ppW, pOrder, pRes, n)) { cout << endl << "比賽名次為:(大到小)" << endl; for (int i32I = 0; i32I < n; i32I++) cout << pRes[i32I] << " "; } //don't forget to free memory... return 0; }
http://www.tuicool.com/articles/jq2INv
用變數i k的跳躍實現每一輪的隊伍選取。 二維指標傳參的地方可以改進。
#include<iostream> using namespace std; #define N 5 void GetResult(int (*w)[N], int* order, int* result) { int i = 0; int k = 1; int j = N -1; while(1) { i = 0; if(i + k > N -1) { result[j] = order[0]; break; } while(i + k <= N-1) { int ii = order[i]; int jj = order[i+k]; if(w[ii][jj] == ii) result[j--] = jj; else { result[j] = ii; order[i]= order[i+k]; order[i+k] = result[j]; j --; } i = i + 2*k; } k *= 2; } } int main() { int a[5][5] = {{0,1,2,3,4},{1,1,2,3,4},{2,2,2,3,4},{3,3,3,3,4},{4,4,4,4,4}}; int order[5] = {4,3,1,2,0}; int result[5]; GetResult(a, order, result); int i = 0; cout << "result order: "; while(i < 5) { cout << result[i++] << ","; } cout << endl; }