网球循环赛比赛日程表n为奇数问题

本文详细介绍了如何解决网球循环赛中,当参赛人数为奇数时的比赛日程表构造问题。通过分治法,分析了算法思路,包括横向和纵向构造方法,并提供了C++代码实现。算法的时间复杂度为O(n^2)。
摘要由CSDN通过智能技术生成

初衷

在教材上看到这个问题的时候,对于奇数的处理百思不得其解,然而网上的答案要么就是n=2k的情况,要么就是自己根本都没有理解,给你讲了一大堆,各种情况,很麻烦,甚至有些是错的误人子弟。所以写下这篇思路,分享给各位。其实这个问题的核心就是分治的治该怎么去构造的问题。

问题

设有N个运动员要进行网球循环赛,设计一个满足以下要求的比赛日程表

(1)每个选手必须与其他n-1个选手各赛一次

(2)每个选手一天只能赛一次

(3)当n 是偶数,循环赛进行n-1天,当n是奇数,循环赛进行n天。

算法分析

  1. 我们采用分治法,先算出n/2的情况,然后进行合并,构造出n的情况。难点就在于构造过程,设第i个选手第j天比赛的队员为A[i][j]。
  2. 若m = n/2为偶数,这时候我们知道偶数人数已经算出了前m个队员的前passed_days天(对于偶数而言是m-1,对于奇数是m)的比赛情况,我们怎么构造呢?
    • 先横向构造,也就是构造出后m个队员在前m-1天的比赛情况,那么为了保证不重复我们采用递增的构造方式,让i+m号选手与比A[i][j]大m的选手比赛,也是是说
      • A[i + m][j] = A[i][j] + m; (1≤i≤m,1≤j≤passed_days,i代表队员,j代表当前比赛的天数)
      • 可以看出来一定不会重复,因为前m个队员之前从未与后m个队员比赛过,然后A[i][j]彼此又是互不相同的,所以A[i+m]彼此也一定不相同
    • 再纵向构造,设n个队员比赛所需总天数为days(对于偶数而言是n-1,对于奇数是n),也就是说构造n个队员在后(days - passed_days)天的比赛情况,同样为了保证不重复我们也采用增量构造,
      • passed_days +1≤j≤days,
      • rvalue = (count + i-1)%m + m+1;//保证i队员与后面的队员(rvalue必然大于m)比赛,这样就与前面passed_days天的比赛不重复
      • count为增量初始值为0,j每加1,count++
      • A[i][j] = rvalue;
      • A[rvalue][j] = i; //因为是两两比赛,后面m对用中的与之对应个队员直接构造出来
    • 需要注意的是纵向构造的时候我们先构造A[1][j]也就是说先保证第一个队员在(days - passed_days)比赛的队员肯定与之前(passed_days)是不同的,那么由于i也是递增的所以,A[i][j]彼此之间必定也是互不相同的!
  • 举个栗子:假设n=4.

先计算n/2 = 2,我们知道A[1][1] = 2,A[2][1] = 1(偶数比赛只有一天)

1 2(队员编号)

2 1(第一天)
复制代码
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值