单循环比赛的"贝格尔"编排法

来源:互联网 发布:买家怎么进淘宝直通车 编辑:程序博客网 时间:2024/04/30 22:42
 单循环是指所有参赛队在竞赛中均能相遇一次,最后按各队在竞赛中的得分多少、胜负场次来排列名次。 单循环一般在参赛队不太多,又有足够的竞赛时间才能采用。单循环由于参加竞赛的各队都有相遇比赛的机会, 是一种比较公平合理的比赛制度。

一) 单循环比赛的轮数和场数的计算

① 比赛轮数:在循环制的比赛中,各队都参加完一场比赛即为一轮。
     参加比赛的队数为单数时,比赛轮数等于队数。如5个队参加比赛,即比赛轮数为五轮。
    参加比赛的队数为双数时,比赛轮数等于队数减一。如6个队参加比赛,则比赛轮数为五轮。

② 比赛场数:单循环比赛的场数,可用下面的公式计算(简单的数学组合公式):

比赛场数= 队数*(队数-1)/2

如6个队或7个队参加比赛,则比赛场数为:

6 *(6-1)/2 =15(场) 7*(7-1)/2 =21(场)

二)编排竞赛轮次表
       不论参赛队是奇数或偶数,均按偶数进行编排。如果参赛队为奇数,则在队数最后加一个“0”,使其成为
偶数。碰到0的队轮空。在编排时,把参赛队平均分成左、右各一半,左一半号数由序号1依次自上向下排,右一半号数按数序依
次自下向上排,然后用横线相连,即构成比赛的第一轮。从第二轮开始,轮转的方法有多种。

常用的有两种:

(1) 固定轮转编排法

 固定轮转法也叫常规轮转法,是我国传统的编排方法。表17-6为7个队参赛轮次表,它以左边第一号固定不动,逆时针转动,逐一排出。

如表所示:

JAVA 程序如下

public class FootBallTeam {
public static void main(String [] args)
{
String [] team = {"1","2","3","4","5","0"};//参赛的各队
int len = team.length;
for(int i=1;i< len;i++) {
System.out.println();
System.out.println("第"+i+" 轮");
for(int j=0;j< len/2;j++)
{
System.out.println(team[j]+" ----- "+ team[len-1-j]);
}
String temp=team[len-1]; //将最后一队的值赋给临时变量temp
for(int k=len-1;k>0;k--)
{
team[k]=team[k-1];
}
team[1]=temp; //将临时变量temp赋给数组的第二值
}
}
}

运行结果:

C:/java>java FootBallTeam

第1 轮
1 ----- 0
2 ----- 5
3 ----- 4

第2 轮
1 ----- 5
0 ----- 4
2 ----- 3

第3 轮
1 ----- 4
5 ----- 3
0 ----- 2

第4 轮
1 ----- 3
4 ----- 2
5 ----- 0

第5 轮
1 ----- 2
3 ----- 0
4 ----- 5


(2)“贝格尔”编排法

      从1985年起,世界性比赛多采用“贝格”“编排法。其优点是单数队参加时可避免第二轮的轮空队从第四轮起每场都与前一轮的轮空队比赛的不合理现象。

      采用“贝格尔”编排法,编排时如果参赛队为双数时,把参赛队数分一半(参赛队为单数时,最后以“0”表示形成双数),前一半由1号开始,自上而下写在左边;后一半的数自上而下写在右边,然后用横线把相对的号数连接起来。这即是第一轮的比赛。

     第二轮将第一轮右上角的编号(“0”或最大的一个代号数)移到左角上,第三轮又移到右角上,以此类推。
即单数轮次时“0”或最大的一个代号在右上角,双数轮次时则在左上角。如下表示:
      
7
个队比赛的编排方法

第一轮

第二轮

第三轮

第四轮

第五轮

第六轮

第七轮

10

05

20

06

30

07

40

27

64

31

75

42

16

53

36

73

47

14

51

25

62

45

12

56

23

67

34

71

无论比赛队是单数还是双数,最后一轮时,必定是“0”或最大的一个代号在右上角,“1”在右下角。

根据参赛队的个数不同,“1”朝逆时针方向移动一个位置时,应按规定的间隔数移动(见表),“0”或最大代号数应先于“1”移动位置。

   间隔移动

参赛队数

间隔数

4队以下

0

5~6

1

7~8

2

9~10

3

11~12

4

       1”进行间隔移动时,凡遇到“0”或最大代号数时应先越过,不作间隔计算。

       一般国内比赛,各队以上届比赛所取得的名次数作为代号,如第1名为“1”,第2名“2”,依此类推。世界性比赛大都采用东道主代号为“1”,上届第1名为“2”,依此类推。有的比赛也采用抽签方法确定代号。


最后是"贝格尔"排法的java程序:

import java.util.Scanner;
public class Test{
public static void main(String args[]){
int team_Num;//队伍的数量
int team_Arr[];//队伍数组
int team_temp[];
boolean empty=false;//是否有轮空
int jump;//调动幅度
int round;//比赛轮数
int flag;//标志,队伍的最大的,或者0,其他队伍在移动的时候,如果碰到他,将跳过
int tempNum,tempNum1;//队伍在迭代时候保存临时变量的东西
//--------------------初始化一些数据
Scanner cin = new Scanner(System.in);
System.out.print("输入队伍的数量: ");

team_Num = cin.nextInt();
if(team_Num%2 != 0)//队伍个数为奇数时
{
empty = true;
team_Num++;
}
round = team_Num-1;
jump = ((team_Num+1)/2)-1;
team_Arr = new int[team_Num];
team_temp = new int[team_Num];
for(int i = 0;i< team_Num;i++){
team_Arr[i] = i+1;
}
if(empty)
{
team_Arr[team_Num-1]=0;
}
flag = team_Num-1;
//---------------------开始计算了--------------
for(int j = 0;j< round;j++)
{
System.out.println("第"+(j+1)+"轮:");
for(int m = 0;m< team_Num/2;m++)
{
System.out.println(team_Arr[m]+"----"+team_Arr[team_Num-m-1]);
}
for(int g = 0;g< team_Num;g++)
{
team_temp[g] = team_Arr[g];
}
if(flag != 0 )
{
tempNum = team_Arr[flag];//temp 一开始总是记录0队或者最大队伍
flag = 0;//flag 跳动
tempNum1 = team_Arr[flag];
team_Arr[flag] = tempNum;

}
else
{
tempNum =team_Arr[flag];//temp 一开始总是记录0队或者最大队伍
tempNum1 = team_Arr[team_Num-1];
flag = team_Num-1;//flag 跳动
team_Arr[flag]=team_temp[flag] = tempNum;
team_Arr[0]=team_temp[0] = tempNum1;

}
for(int k = 0;k< team_Num-1;k++)//走动
{
int t = k;

if(t >= team_Num)
t = t - team_Num;
int z = t;

for(int u = 0;u< jump;u++)
{
t++;
if(t == team_Num)
t = t - team_Num;
if(t == flag)
t++;
if(t == team_Num)
t = t-team_Num;
}

team_Arr[t] = team_temp[z];//
}
}
}
}


更精简的程序(我的朋友写的):

import java.util.Scanner;
public class Test1{
public static void main(String[] args){
int n,m;
Scanner cin = new Scanner(System.in);
System.out.print("输入队伍的数量: ");
n= cin.nextInt();
if(n%2==0) m=n;
else m=n+1;
int a=1,b=1,index=1,loop=0;
for(int i=1; i<=(m-1)*(m/2); i++)
{
if(a>=m) a=1;
if(index>m/2) index=1;
if(index==1){
loop++;
if(i==1){
b=m;
}else{
b=a;
}
System.out.println("第"+loop+"轮");;
if(((i-1)/(m/2))%2==0){
System.out.println(a+"--"+m);
}else{
System.out.println(m+"--"+a);
}
}else if(index>1 && index<=m/2){
if(b>1) b--;
else b=m-1;
System.out.println(a+"--"+b);
}
index++;
a++;
}

}
}

程序运行结果:


C:/java>java Test1
输入队伍的数量: 12
第1轮
1--12
2--11
3--10
4--9
5--8
6--7
第2轮
12--7
8--6
9--5
10--4
11--3
1--2
第3轮
2--12
3--1
4--11
5--10
6--9
7--8
第4轮
12--8
9--7
10--6
11--5
1--4
2--3
第5轮
3--12
4--2
5--1
6--11
7--10
8--9
第6轮
12--9
10--8
11--7
1--6
2--5
3--4
第7轮
4--12
5--3
6--2
7--1
8--11
9--10
第8轮
12--10
11--9
1--8
2--7
3--6
4--5
第9轮
5--12
6--4
7--3
8--2
9--1
10--11
第10轮
12--11
1--10
2--9
3--8
4--7
5--6
第11轮
6--12
7--5
8--4
9--3
10--2
11--1