必威体育Betway必威体育官网
当前位置:首页 > IT技术

单循环赛贝格尔编排法实现

时间:2019-07-01 10:42:17来源:IT技术作者:seo实验室小编阅读:64次「手机版」
 

单循环赛

单循环赛,是指所有参赛队伍都需跟其他队伍比赛一次,根据比赛得分,胜负场次来排列名次。比赛队伍为单数时,轮数等于队伍数,为双数时,轮数等于队伍数减一。如5支队伍需比赛5轮,6支队伍需比赛5轮。

首先介绍下逆时针轮转法。将队伍用阿拉伯数字从1开始编号,编排时将参赛队伍平均分成左右两排,左边从1开始自上向下排,右边按号数自下向上排,形成一个U型结构。如果队伍数为奇数,则在最后加一个“0”,凑成偶数。与0比赛的队伍该轮轮空。假设现在有7支队伍参赛,加上一个0,凑成8支。根据前面所述排列好队伍,然后将左右两排分别平行连线,就形成第一轮比赛的编排表,即1-0,2-7,3-6,4-5,队伍1在该轮轮空。第二轮开始,固定左上角的数字1,其余的数字想象成一个环,按逆时针方向移动一个位置,就形成第二轮的编排表。以此类推,每一轮移动一个位置,生成剩余轮次的编排表。最终形成的编排表如下:

一    二     三     四    五     六    七

1—0 1—7 1—6 1—5 1—4 1—3 1—2

2—7 0—6 7—5 6—4 5—3 4—2 3—0

3—6 2—5 0—4 7—3 6—2 5—0 4—7

4—5 3—4 2—3 0—2 7—0 6—7 5—6

仔细观察,会发现从第4轮开始,队伍6总是跟上一轮轮空的队伍比赛,这就是逆时针轮转法的缺点,即第二轮的轮空队从第四轮开始,每轮都与前一轮的轮空队伍比赛。

贝格尔编排法与逆时针轮转法类似,不过有两个区别。一是交替固定最大的数字(或者0)在左上角和右上角,当前轮次在左上角,则下一轮固定到右上角。二是固定最大数字(或者0)后,剩余的数字想象成一个环,移动一定间隔,这个间隔根据队伍数决定:

队伍数 间隔数

<=4      0

5 - 6      1

7 - 8      2

9 -10     3

11-12    4

13-14    5

...         ...

假设有n(n>=4)支队伍参赛,则间隔数的计算公式为(n+n%2-4)/2。

同样以7支队伍参赛为例,首轮还是

1 - 0

2 - 7

3 - 6

4 - 5

第二轮将0移到左上角,剩下的数字从1开始逆时针移动2个间隔,这里1将移到原来4所在的位置

第三轮将0移动到右上角,剩下的数字继续逆时针移动2个间隔

剩下的轮次原理同上,最终编排表如下

代码实现的思路如下,最大数字的位置只需根据前一轮的位置就能确定,其他数字都是按顺序排列,形成一个有序的环。所以只需要确定1的位置,其他位置的数字都能确定。将位置按照第一轮的数字编号为1-8。在第一轮,1在位置1上。第二轮,1移动2个间隔,可以理解成移动3个位置,即1+3=4,取模一下,(1+3)%7=4,所以1将移到位置4。第三轮,继续移动3个位置,(4+3)%7=0,这里0就是7,也就是1移到位置7。第四轮,(7+3)%7=3,1移到位置3。以此类推。要注意的是,要是1移到的位置跟0冲突,就移到相对位置。0在位置8,那么1就移到位置1,0在位置1,1就移到位置8。

1 void BegerArrangement(intnAmount)

2 {

3     if (nAmount < 2 ||nAmount > 90 )

4         return;

5

6     // 队伍数量

7     int nFixAmount = nAmount;

8     // 最后一支队伍的编号

9     int nLastPlayerNo = nAmount;

10     // 奇数队伍,补上一支虚拟的队伍,最后一支队伍的编号为0

11     if(IsOdd(nAmount))

12     {

13         ++nFixAmount;

14         nLastPlayerNo = 0;

15     }

16     // 轮数

17     intnMaxRound = nFixAmount-1;

18     intnHalfAmount = nFixAmount / 2;

19

20     // 移动的间隔

21     intnStep = nFixAmount <= 4 ? 1 : (nFixAmount - 4) / 2 + 1;

22

23     intnRound = 1;

24     intnFirstPlayerPos = 1;

25     intnLastPlayerPos = 1;

26     intresult[100][200] = { 0 };

27     while(nRound <= nMaxRound)

28     {

29         // 每次最后一个玩家的位置需要左右对调

30         nLastPlayerPos = nFixAmount + 1 - nLastPlayerPos;

31

32         if(nRound == 1)

33             nFirstPlayerPos = 1;

34         else

35             nFirstPlayerPos = (nFirstPlayerPos+ nStep) % (nFixAmount - 1);

36

37         if(nFirstPlayerPos == 0)

38             nFirstPlayerPos = nFixAmount - 1;

39

40         if(nFirstPlayerPos == nLastPlayerPos)

41             nFirstPlayerPos = nFixAmount + 1 - nLastPlayerPos;

42

43         for (int i = 1; i<= nHalfAmount; ++i)

44         {

45             int nPos[2] = { i, nFixAmount - i + 1 };

46             int nPlayer[2] = { 0, 0};

47             for (int j = 0; j < 2;++j)

48             {

49                 if (nPos[j] == nLastPlayerPos)

50                     nPlayer[j] =nLastPlayerNo;

51                 else if (nPos[j] <nFirstPlayerPos)

52                     nPlayer[j] = nFixAmount -nFirstPlayerPos + nPos[j];

53                 else

54                     nPlayer[j] = nPos[j] -nFirstPlayerPos + 1;

55

56                 result[i-1][(nRound-1)*2+j] = nPlayer[j];

57             }

58         }

59

60         ++nRound;

61     }

62

63     for (int i = 1; i<= nMaxRound; ++i)

64     {

65         if( i ==1 )

66             printf("%3s%-3d|", "r", i);

67         else

68             printf("%4s%-3d|", "r", i);

69     }

70     printf("\n");

71

72     for (int i = 0; i< nHalfAmount; ++i)

73     {

74         for (int j = 0; j< nMaxRound; ++j)

75         {

76             printf("%-2d-%2d | ", result[i][j*2], result[i][j*2+1]);

77         }

78         printf("\n");

79     }

80

81     printf("\n\n");

82 }

代码地址

https://github.com/windpenguin/WindUtilities

参考

http://www.xxkt.cn/zhxk/2007/24920.html

http://baike.baidu.com/item/%E5%8D%95%E5%BE%AA%E7%8E%AF%E8%B5%9B%E5%88%B6?sefr=enterbtn

http://baike.baidu.com/item/%E8%B4%9D%E6%A0%BC%E5%B0%94%E7%BC%96%E6%8E%92%E6%B3%95?sefr=enterbtn

相关阅读

数据结构之二叉排序树(C语言实现)

一、基本概念 1.二叉排序树 二叉排序树(Binary sort tree,BST),又称为二叉查找树,或者是一棵空树;或者是具有下列性质的二叉树: (1)若

如何用新浪微博做淘宝客,三步实现破零

第一步,注册一个有趣味的微博名字,如减肥瘦身百科,护肤美妆百科,美食营养百科。这样做的目的是便于搜索,目前也是女生关注最多的话题。

Python实现求二阶行列式

目录 题目描述 输入/输出描述 解决思路 代码 代码走读 传送门 测试用例 1. 输入的数据都是整型 2. 输入的数据存在非法字符 题

使用socks5实现简易代理服务器

写一个简易的socks5代理服务器,负责转发网络数据包,要能够使用它来上网。 SOCKS5 是一个代理协议,它在使用TCP/IP协议通讯的前端机器

CountDownLatch的实现

这是一个非常有意思的类,看下面的代码:CountDownLatch countDownLatch = new CountDownLatch(1); new Thread(new Runnable() {

分享到:

栏目导航

推荐阅读

热门阅读