![df9a9d7041d581b9587a2b897d6690dd.png](https://i-blog.csdnimg.cn/blog_migrate/95cd4e82c88e2a47424b186fa24af568.jpeg)
一、问题背景
设有n=2k个选手要进行网球循环赛,要求设计一个满足以下要求的比赛日程表:
①每个选手必须与其他n-1个选手各赛一次;
②每个选手一天只能赛一次。
二、问题分析
按此要求,可将比赛日程表设计成一个n×(n-1)的二维表,其中,(i, j)表示和第i个选手在第j天比赛的选手。
•将所有参赛的选手分为两部分
n=2^k个选手的比赛日程表就可以通过为n/2=2^(k-1)个选手设计的比赛日程表来决定。
•递归地执行这种分割
•直到只剩下2个选手(递归出口)
比赛日程表的制定就变得足够简单 只要让这2个选手进行比赛即可
•求解过程是自底向上的迭代过程,其中图(c)左上角和左下角分别为选手1至选手4以及选手5至选手8前3天的比赛日程
•将左上角部分的所有数字按其对应位置抄到右下角,将左下角的所有数字按其对应位置抄到右上角,这样,就分别安排好了选手1至选手4以及选手5至选手8在后4天的比赛日程,如图(c)所示。具有多个选手的情况可以依此类推。
![e7c2df67b9ecebf9da1e87113823c308.png](https://i-blog.csdnimg.cn/blog_migrate/24d849ee6b384e105f1506a6661da284.png)
•把求解2k个选手比赛日程问题划分成依次求解21、22、…、2k个选手的比赛日程问题,换言之,2k个选手的比赛日程是在2^(k-1)个选手的比赛日程的基础上通过迭代的方法求得的。
•在每次迭代中,将问题划分为4部分:
①左上角
•左上角为2^(k-1)个选手在前半程的比赛日程;
②左下角
•左下角为另2^(k-1)个选手在前半程的比赛日程,由左上角加2^(k-1)得到,例如22个选手比赛,左下角由左上角直接加2得到,23个选手比赛,左下角由左上角直接加4得到;
③右上角
•将左下角直接抄到右上角得到另2^(k-1)个选手在后半程的比赛日程;
④右下角
•将左上角直接抄到右下角得到2^(k-1)个选手在后半程的比赛日程;
算法设计的关键在于寻找这4部分元素之间的对应关系
三、算法描述
void
四、时间复杂度分析
迭代处理的循环体内部有3个循环语句,每个循环语句都是一个嵌套的for循环,且他们的执行次数相同,基本语句是最内层循环体的赋值语句,即填写比赛日程表中的元素。基本语句的执行次数是:
![50556318a55d406605a12aa6bf9d118a.png](https://i-blog.csdnimg.cn/blog_migrate/3a2015c018a2e98e822439c8b2b72812.png)
故其时间复杂性为O(4^k)。