循环赛日程表
设有n位选手参加网球循环赛,循环赛共进行n-1天,每位选手要与其他n-1位选手比赛一场,且每位选手每天必须比赛一场,不能轮空。试按此要求为比赛安排日程。
思路:
用递归方法编写的问题解决程序具有结构清晰,可读性强等优点,且递归算法的设计比非递归算法的设计往往要容易一些,所以当问题本身是递归定义的,或者问题所涉及到的数据结构是递归定义的,或者是问题的解决方法是递归形式的时候,往往采用递归算法来解决。
代码如下:
#include<iostream>
#include<vector>
#include<iterator>
using namespace std;
const int n=8; // number of people entering this cyclic scheduling.
bool confronted(int arr[][n-1], // the cyclic scheduling table
int i, // the i-th person (zero-based index)
int j, // the j-th person
int col // the col-th column, or equivalently the col-th game day
)
{// true if up until the col-th game day,
// i-th and j-th person hasn't competed with each other.
if(i==j) // Assume that a person has already competed with himself.
return true;
for(int k=0; k<col; k++) // the days before the col-th day
if(arr[i][k]==j)
return true;
for(int k=0; k<i; k++) // on the col-th day
if(arr[k][col]==j)
return true;
return false;
}
void cyclic_schedule(int arr[][n-1], int col)
{
if(col == n-1)
return;
else
{
for(int i=0; i<n; i++)
{
int j=0;
for(j=0; j<n; j++)
if(!confronted(arr,i,j,col))
break;
if(arr[j][col]==n)
{
arr[i][col] = j;
arr[j][col] = i;
}
}
cyclic_schedule(arr,col+1);
}
}
int main()
{
// the following table is the cyclic scheduling table
// arr[i][j]: the person that i will be competing with on the j-th day
// index is zero-based.
int arr[n][n-1];
for(int i=0; i<n; i++)
for(int j=0; j<n-1; j++)
arr[i][j]=n;// n: no schedule is made yet.
cyclic_schedule(arr, 0);
for(int i=0; i<n; i++)
{
for(int j=0; j<n-1; j++)
cout<<arr[i][j]<<"|";
cout<<"\n";
}
}
运行结果如下:
方法二:
方法二采用分治法。其核心也是一个递归函数。
#include<stdio.h>
#include<stdlib.h>
#include<iostream>
using namespace std;
const int n = 8;
// Another method to solve this problem.
// Devide and Conque
// cyclic_schedule2:
// design a schedule for the competitors in [r1, r2]
// arr: the schedule table
// r1: the r1-th row (0-based index)
// r2: the r2-th row (0-based index)
void cyclic_scheduling2(int arr[][n-1], int r1, int r2)
{
if(r1==r2-1)
{
arr[r1][0] = r2;
arr[r2][0] = r1;
}
else
{
int count = r2-r1+1;
cyclic_scheduling(arr, r1, r1+count/2-1 ); //schedule for competitors in [r1, r1+count/2-1]
cyclic_scheduling(arr, r1+count/2, r2); //schedule for competitors in [r1+count/2, r2]
// The following code will arrange competitions between the first and second half of [r1,r2]
for(int i=0; i<count/2; i++)
for(int j=0; j<count/2; j++)
{
arr[r1+j][count/2+i-1] = r1+count/2+(j+i)%(count/2); // a person from the first half
arr[r1+count/2+j][count/2+i-1] = r1+(j+i)%(count/2); // a person from the second half
// these two persons will compete with each other
}
}
}
int main()
{
int arr[n][n-1];
for(int i=0; i<n; i++)
for(int j=0; j<n-1; j++)
arr[i][j]=n;// n: no schedule is made yet.
cyclic_scheduling2(arr, 0,7);
for(int i=0; i<n; i++)
{
for(int j=0; j<n-1; j++)
cout<<arr[i][j]<<"|";
cout<<"\n";
}
}
运行结果如下: