算法描述:以足球为例:n(n为偶数)只队伍,每只队伍要跟其他队伍每天都进行一场比赛,共n-1场比赛,需要n-1天,一只队伍一天只能进行一场比赛。
算法实现:对n支队伍进行编号,以第一只队伍为例需要跟其他n-1只队伍进行比赛,但是对于每只队伍来说都在进行比赛,因此同一天内会有n/2场比赛。于是将所有队伍排成2排,每排队伍数量为n/2,排好之后为第一天的比赛对局,第二天的时候固定第一排第一支队伍,然后其他队伍进行顺时针或者逆时针旋转(仍然要保证每排队伍数量为n/2),旋转后的即为第二天的对局(这样既保证每个队伍都有比赛,又不会出现一只队伍在同一天有两场比赛),这种做法相当于每旋转一次进行一次错位排列,当旋转一周后,第一只队伍已经与其他n-1只队伍都进行了一次比赛,响应的其他队伍也都进行了n-1次比赛
算法模拟:
这里以6只队伍为例(比赛有5天,每天3场比赛),模拟一下比赛赛程:
第一天:
1 2 3
6 5 4
第二天:
1 3 4
2 6 5
第三天:
1 4 5
3 2 6
第四天:
1 5 6
4 3 2
第五天:
1 6 2
5 4 3
算法实现(java):
- public static void main(String[] args) {
- int n = 6;
- List
teams = new ArrayList<>(); - teams.add("队伍1");
- teams.add("队伍2");
- teams.add("队伍3");
- teams.add("队伍4");
- teams.add("队伍5");
- teams.add("队伍6");
- roundRobin(n, teams);
- }
-
- /**
- * 循环赛
- * @param n 比赛队伍数量
- * @param teams 比赛队伍信息
- */
- private static void roundRobin(int n, List
teams) { - for(int i = 0; i< n -1; i++){
- System.out.println("第"+(i+1)+"天比赛********************");
- for(int j = 0; j< n /2; j++){
- String home="",away="";
- if(j==0){
- int rightIndex = i% n ==0? n -1:i% n;
- home = teams.get(j);
- away = teams.get(rightIndex);
-
- }else{
- int rightIndex = 0,leftIndex=0;
- if(j+i< n){
- leftIndex = j+i;
- }else{
- leftIndex = (j+i+1)% n;
- }
- if(j>i){
- rightIndex = (n -j+i)% n -1;
- }else if(j==i){
- rightIndex= n -1;
- }else{
- rightIndex = (n -j+i)% n;
- }
- home = teams.get(leftIndex);
- away = teams.get(rightIndex);
- }
- System.out.println(home + " VS " + away);
- }
- System.out.println("第"+(i+1)+"天比赛********************");
- }
- }
运行结果:
- 第1天比赛********************
- 队伍1 VS 队伍6
- 队伍2 VS 队伍5
- 队伍3 VS 队伍4
- 第1天比赛********************
- 第2天比赛********************
- 队伍1 VS 队伍2
- 队伍3 VS 队伍6
- 队伍4 VS 队伍5
- 第2天比赛********************
- 第3天比赛********************
- 队伍1 VS 队伍3
- 队伍4 VS 队伍2
- 队伍5 VS 队伍6
- 第3天比赛********************
- 第4天比赛********************
- 队伍1 VS 队伍4
- 队伍5 VS 队伍3
- 队伍6 VS 队伍2
- 第4天比赛********************
- 第5天比赛********************
- 队伍1 VS 队伍5
- 队伍6 VS 队伍4
- 队伍2 VS 队伍3
- 第5天比赛********************