单循环比赛队伍编排(非分治算法)纯循环解决
情景:假如有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; } }