单循环比赛队伍编排(非分治算法)纯循环解决
情景:假如有N个队伍要进行单循环比赛,即任何一个队伍要和所有其他队伍进行一次比赛,在一轮比赛中每个队伍只能进行一次比赛,比赛完后不能再和其他队伍比赛,需要等到下一轮。
比赛队伍编排用以下算法:
把队伍按顺序排成一圈,如果队伍为奇数,就添加一个冗余位到首位。现在除了第一位和中间位,其余位置的队伍其水平方向都有一个队伍与其相对,那么水平方向连线的2个队伍就为这一轮比赛的队伍,第一位和中间位为一对(若第一位为冗余的,那么中间的那个队伍这一轮就不用比赛),一轮完成。下一轮首位的不动,队伍以顺时针或逆时针转一个位置,有队伍遇到首位的队伍的就跳过,再移动一位。这样就能形成新的圆圈队伍,按上一次的出赛规则出赛。一直这样循环多次就能把所有的比赛队伍编排分配好。偶数循环N-1次。奇数循环N次。算法JAVA 实现:
public static void main(String[] args) {
get(10); //10个队伍比赛。
}
public static void get(int n) {
int i = 0;
int j = 1;
if((n&1)==1) { //判断队伍是奇数还是偶数
n++;
i = 1;
}
int[] al = new int[n];
for(;i<n;i++) { //队伍赋值,若队伍为奇数,首位赋值就跳过,且冗余值为0
al[i] = j++;
}
move(al,n/2,n); //循环编排开始
}
public static void move(int[] al,int t,int n) { //t为圆圈的中间位置下标
int length = n;
for(int i = 0; i < length-1;i++) {
int test1 = t;
int test2 = 0;
int[] al2 = new int[length]; //al2为下轮循环所用的新圆圈
al2[0] = al[0];
System.out.println("第"+(i+1)+"轮比赛:");
while(test1<=length-1) {
if(al[test2]!=0&&test2==0) {
System.out.println(al[test2]+" VS "+al[test1]);
}
else if(test2!=0){
System.out.println(al[t+test2]+" VS "+al[t-test2]);
}
/*
* 下面算法是为下一轮编排所用圆圈赋值
*/
if(test1==length-1) {
al2[1] = al[test1];
al2[test2+1] = al[test2];
}
else {
al2[test1+1] = al[test1];
if(test2!=0) {
al2[test2+1] = al[test2];
}
}
test1++;
test2++;
}
al = al2;
}
}
浙公网安备 33010602011771号