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  */ 

 

posted @ 2013-04-26 23:56  ningjing@liunian  阅读(122)  评论(0)    收藏  举报