面试100题系列之17模拟比赛

题目描述:有n支球队,编号为0~n-1,随机两两比赛,晋级之后同样,求一个Result序列,表明最后每支球队的名次,如果是在同一轮中被淘汰的,那名次相同。其实以前写过这个题的代码,不过现在看看觉得写得太挫了,所以重新写一下。
思路分析:
这里借用归并排序的思想,其实每次决定两支要比赛的队伍的标号相距多少就可以了,假设队伍i和队伍i+l比赛,不管最后结果怎样,默认胜利的那支球队的编号是存在第i的位置,这样方便安排下一轮比赛。
将两支球队之间的步长跨越从1遍历到nLen-1,就可以遍历到所有的球队,在增大步长的同时,其实就是淘汰掉步长不能覆盖的队伍,不是么?至于一些边界的判断,这需要自己好好思考,毕竟别人给的答案都不是自己的东西。
如果有幸得到青睐,那请转载注明出处:http://blog.csdn.net/kay_zhyu/article/details/8879693
核心代码如下,有没有觉得代码很短很漂亮:

//计算比赛结果
void GetResult(int *Order, int *Result, int nLen)
{
	if(!Order || !Result || nLen < 1)
		return;
	int l,i;
	for(l = 1; l < nLen; l <<= 1)
	{//l为两个队伍之间的跨越的步长
		for(i = 0; i < nLen - l; i += l + l)
		{
			if(rand() < RAND_MAX / 2)
			{//保证Order[i]胜Order[i+l]
				swap(Order[i], Order[i + l]);
			}
			Result[Order[i + l]] = nLen / (l + l) + 2;//输了的名次
			Result[Order[i]] = nLen / (l + l) + 1;//赢了的名次
		}
	}
}
下面给出辅助函数和main函数的定义。
#include<stdio.h>
#include<stdlib.h>
void swap(int &a, int &b)
{
	int temp;
	temp = a;
	a = b;
	b = temp;
}
int main()
{
	const int N = 30;
	int Order[N];
	int Result[N];
	int n,i;
	while(scanf("%d", &n) != EOF)
	{
		for(i = 0; i < n; ++i)
			scanf("%d", &Order[i]);
		GetResult(Order, Result, n);
		for(i = 0; i < n; ++i)
			printf("%d ", Order[i]);
		printf("\n");
		for(i = 0; i < n; ++i)
			printf("%d ", Result[Order[i]]);
		printf("\n");
	}
	return 0;
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值