【程式設計題目】n 支隊伍比賽,分別編號為 0,1,2。。。。n-1,已知它們之間的實力對比關係,...

weixin_34126215發表於2014-08-11

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

 

相關文章