2.11循环赛日程表
问题描述:
设有n=2^k个运动员要进行比赛,设计满足以下要求的比赛日程表:
(1)每个选手必须与其他n-1个选手各赛一次;
(2)每个选手一天只能赛一次;
(3)循环赛一共进行n-1天;
1 #include <iostream> 2 #include <cmath> 3 using namespace std; 4 5 void Table(int k, int n, int **a); 6 void Input(int &k); 7 void Output(int **a, int n); 8 9 int main(){ 10 int k = 0; 11 Input(k); 12 13 int n = 1; 14 //n = 2^k(k>=1)个选手参加比赛 15 for (int i = 1; i <= k; ++i) 16 n *= 2; 17 //根据n动态分配二维数组a 18 int **a = new int *[n + 1]; 19 for (int i = 0; i <= n; ++i) 20 a[i] = new int [n + 1]; 21 22 Table(k, n, a); 23 24 cout << "循环赛事日程表为:" << endl; 25 Output(a, n); 26 27 //释放空间 28 for (int i = 0; i <= n; ++i) 29 delete[] a[i]; 30 delete[] a; 31 return 0; 32 } 33 34 void Input(int &k) { 35 cout << "请输入k值:"; 36 cin >> k; 37 } 38 39 void Output(int **a, int n) { 40 for (int i = 1; i <= n; ++i) { 41 for (int j = 1; j <= n; ++j) 42 cout << a[i][j] << " "; 43 cout << endl; 44 } 45 } 46 47 void Table(int k, int n, int **a) { 48 for (int i = 1; i <= n; ++i) 49 a[1][i] = i;//设置日程表第一行 50 int m = 1; 51 for (int s = 1; s <= k; ++s) { 52 n /= 2; // 53 for (int t = 1; t <= n; ++t) { 54 for (int i = m + 1; i <= 2 * m; ++i) 55 for (int j = m + 1; j <= 2 * m; ++j) { 56 a[i][j + (t - 1) * m * 2] = a[i - m][j - m + (t - 1) * m * 2]; 57 a[i][j - m + (t - 1) * m * 2] = a[i - m][j + (t - 1) * m * 2]; 58 } 59 } 60 m *= 2; 61 } 62 } 63 /* m 为了设置每次填充时的起始位置 ;将原问题划分为 K 步骤解决,S 加以控制步骤的顺序; 64 将每步骤划分为 (n /= 2) 部分,t 控制每部分的初始化顺序; 将(t-1)*m*2 视为每次跨的步距, 65 每次的起始坐标(i, j)是(i, j)从初始位置(1, 1),i 下移 m, j 右移 m 后得到的, 66 若k = 3, 则Table()内 s = {1, 2, 3}; n = {4, 2, 1}; m = {1, 2, 4}; 为对角互相初始化的 67 推导式提供解释。 68 */

浙公网安备 33010602011771号