题意:有n=(1<<k)个运动员进行网球循环比赛,需要设计比赛日程表。每个选手必须与其他n-1个选手各比赛一次。每个选手一天只能赛一次;循环赛一共进行n-1天。
思路:分治法。和棋盘覆盖问题差不多。因为一共有(1<<k)个运动员,则可以递归分解每个表格为(1<<k-1)..(1<<k-2)个运动员。
每次递归的时候,左上角的数字有右下角的第一个数字相同,右上角的第一个数字和左下角的第一个数字相同。计算出来之后再将这个表格分解为四部分继续进行递归。
1 #include<iostream> 2 using namespace std; 3 4 int k, s; 5 int number; 6 int sche[1000][1000]; 7 8 void board(int row,int col,int s) 9 { 10 if (s == 1) return; 11 int t = s / 2; 12 //每次计算出每个表格左上角的第一个 13 sche[row + t][col + t] = sche[row][col]; 14 sche[row][col + t] = sche[row + t][col] = sche[row][col] + t; 15 //递归分解的四个表格 16 board(row, col, t); 17 board(row + t , col, t); 18 board(row, col + t, t); 19 board(row + t , col + t, t); 20 } 21 22 int main() 23 { 24 while (cin >> k) 25 { 26 memset(sche, 0, sizeof(sche)); 27 sche[1][1] = 1; 28 s = 1 << k; //总人数 29 board(1,1,s); 30 for (int i = 1; i <= s; i++) 31 { 32 for (int j = 1; j <= s; j++) 33 cout << sche[i][j] << " "; 34 cout << endl; 35 } 36 } 37 return 0; 38 }