算法习题36:n支队伍比赛,分别编号为0,1,2。。。。n-1,已知它们之间的实力对比关系

本文探讨了一道编程题目,涉及n支队伍的比赛情况,根据实力对比关系进行比赛顺序安排。通过分析,将问题转化为一个堆排序问题,重点在于实现Promote()函数以调整比赛顺序。在处理奇数队伍时需要设定规则,并且可以通过优化空间使用,直接利用order数组存储比赛结果。这是一个简化版的堆排序算法应用。

http://bbs.csdn.net/topics/350118968

引用自网友:longzuo

谷歌笔试:
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。

---------------------------------------------------------------------------------------------------------------------------------------------------------

一直都觉得Google的题目非常有意思!不是死板的在算法上,而是结合实例。

不过这道题好像难度不是很大,也许是我考虑问题不够才这么觉得把.

有几个问题要考虑进来

(1)这里就是希望我们根据队伍出场顺序来获得比赛结果,幸好不需要再对淘汰队伍排名了,不然稍微复杂了,

(2)这里题目没有说到当两两比赛发现最后一个队伍没有比赛对手的时候,就是奇数队伍,改如何处理,我们这里应该定一个规则。

(3)给的实力对比数组 应该是一个对称矩阵,但如果这里分主客场,那又不一定了,所以这里的矩阵该如何对待是一个可以挖掘的地方。。。

废话太多了。。。

这里大家都觉得可以利用一个数组盛放result,但其实这个空间是可以节省的,我们可以直接利用order[]这个数组来存放最终结果。。

大家想想比赛图是不是都是一个树状结构,这里比赛也是如此,其实就是一个排序问题,只不过不是根据数字本身,而是根据实力对照表罢了

如果熟悉堆排序的,那么你会发现,哦,原来这道题就是一个堆排序罢了!!

而且只需要生成一个最大堆的一步就够了,后面都不需要再排序了,比堆排序还更简单!

所以这里程序主要的是Promote()这个函数 实现了堆排序的关键一步

就是把比赛淫的家伙排到前面,这样只需要对前面的进行比赛即可,队伍数也每次都减半

//============================================================================
// Name        : CompetitionWinner.cpp
// Author      : YLF
// Version     :
// Copyright   : Your copyright notice
// Description : Hello World in C++, Ansi-style
//============================================================================

#include <iostream>
using namespace std;
#define MAX 10
/*
 * just like a heap sort!!
 */
void Competition(int** matrix, int row, int col, int* order, int n);
void Promote(int *order, int index);

int main() {

	int i = 0, j = 0;
	int n = 0;

	int *matrix[MAX];
	for(i=0;i<MAX;i++)
		matrix[i] = new int[MAX];
	int order[MAX];

	//输入队伍实力对比
	cin>>n;
	for(i=0;i<n;i++)
		for(j=0;j<n;j++)
			cin>>matrix[i][j];

	//输入队伍参赛顺序
	for(i=0;i<n;i++)
		cin>>order[i];

	//比赛
	Competition(matrix, n, n, order, n);

	//比赛结果
	cout<<"比赛结果排名:";
	for(i=0;i<n;i++)
		cout<<order[i]<<" ";

	return 0;
}

void Competition(int** matrix, int row, int col, int* order, int n){
	int i = 0, j =0, index = 0;
	int winner = 0;

	while(n>1){
		for(index=0;index<n;index+=2){
			if(index+1 < n){
				//偶数
				winner = matrix[order[index]][order[index+1]];
				if(winner == order[index])
					Promote(order,index);
				else
					Promote(order, index+1);
			}else{
				//奇数,这里作直接晋级处理
				Promote(order,index);
			}
		}
		n = (n+1)/2;
	}
}

void Promote(int *order, int index){
	int temp = order[index];
	order[index] = order[index/2];
	order[index/2] = temp;
}

4
0 1 0 3
1 1 2 1
0 2 2 2
3 1 2 3
2 0 1 3
比赛结果排名:1 0 2 3 


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值