• 【赛程问题】 有N个运动员进行单循环赛,即每个运动员要和所有其他运动员进行一次比赛。 试用分治法为这N个运动员安排比赛日程。 – 要求每个运动员每天只进行一场比赛, – 且整个赛程在N -1天内结束。 – 将运动员从1到N编号 #include <iostream> using namespace std; #define N 100 int a[N][N]; int b[N]; void copy(int n) { int m=n/2; for(int i=0;i<m;i++) for(int j=0;j<m;j++) { //由左上角小块的值算出对应的右上角小块的值 a[i][j+m]=a[i][j]+m; //由右上角小块的值算出对应的左下角小块的值 a[i+m][j]=a[i][j+m]; //由左上角小块的值算出对应的右下角小块的值 a[i+m][j+m]=a[i][j]; } } void copyodd(int n) // n/2为奇数时的合并算法 { int m=n/2; for(int i=0;i<m;i++) { b[i]=m+i; b[m+i]=b[i]; } for(i=0;i<m;i++) { //由左上角小块的值算出相应的左下角小块的值 for(int j=0;j<m+1;j++) { if(a[i][j]>=m) { a[i][j]=b[i]; a[m+i][j]=(b[i]+m)%n; } else a[m+i][j]=a[i][j]+m; } //由左上角小块的值算出相应的右上角和右下角小块的值 for(j=1;j<m;j++) { a[i][m+j]=b[i+j]; a[b[i+j]][m+j]=i; } } } bool odd(int n) { return n&1; } void makecopy(int n) { if((n/2)>1&&odd(n/2)) copyodd(n); else copy(n); } void tourna(int n) { if(n==1) { a[0][0]=0; return; } if(odd(n)) { tourna(n+1); return; } tourna(n/2); makecopy(n); } void main() { int n,i,j; cin >> n; tourna(n); if(!odd(n)) { for (i=0; i<n;i++) { if(i==0) cout<<" "; else if(i<10) cout<< "第"<<i<<"天 "; else cout << "第"<<i<<"天 "; for(j=0; j<n;j++) cout <<a[i][j]+1<<" "; cout <<endl; } } else { for (i=0; i<=n;i++) { if(i==0) cout<<" "; else if(i<10) cout<< "第"<<i<<"天 "; else cout << "第"<<i<<"天 "; for(j=0; j<=n;j++) cout <<a[i][j]+1<<" "; cout <<endl; } } }