1. 程式人生 > >單迴圈比賽的"貝格爾"編排法

單迴圈比賽的"貝格爾"編排法

單迴圈是指所有參賽隊在競賽中均能相遇一次,最後按各隊在競賽中的得分多少、勝負場次來排列名次。 單迴圈一般在參賽隊不太多,又有足夠的競賽時間才能採用。單迴圈由於參加競賽的各隊都有相遇比賽的機會, 是一種比較公平合理的比賽制度。

一) 單迴圈比賽的輪數和場數的計算

① 比賽輪數:在迴圈制的比賽中,各隊都參加完一場比賽即為一輪。

     參加比賽的隊數為單數時,比賽輪數等於隊數。如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個隊比賽的編排方法

第一輪

第二輪

第三輪

第四輪

第五輪

第六輪

第七輪

1-0

0-5

2-0

0-6

3-0

0-7

4-0

2-7

6-4

3-1

7-5

4-2

1-6

5-3

3-6

7-3

4-7

1-4

5-1

2-5

6-2

4-5

1-2

5-6

2-3

6-7

3-4

7-1

無論比賽隊是單數還是雙數,最後一輪時,必定是“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