2.11循环赛日程表
2013-04-26 23:56
351 查看
问题描述:
设有n=2^k个运动员要进行比赛,设计满足以下要求的比赛日程表:
(1)每个选手必须与其他n-1个选手各赛一次;
(2)每个选手一天只能赛一次;
(3)循环赛一共进行n-1天;
设有n=2^k个运动员要进行比赛,设计满足以下要求的比赛日程表:
(1)每个选手必须与其他n-1个选手各赛一次;
(2)每个选手一天只能赛一次;
(3)循环赛一共进行n-1天;
#include <iostream> #include <cmath> using namespace std; void Table(int k, int n, int **a); void Input(int &k); void Output(int **a, int n); int main(){ int k = 0; Input(k); int n = 1; //n = 2^k(k>=1)个选手参加比赛 for (int i = 1; i <= k; ++i) n *= 2; //根据n动态分配二维数组a int **a = new int *[n + 1]; for (int i = 0; i <= n; ++i) a[i] = new int [n + 1]; Table(k, n, a); cout << "循环赛事日程表为:" << endl; Output(a, n); //释放空间 for (int i = 0; i <= n; ++i) delete[] a[i]; delete[] a; return 0; } void Input(int &k) { cout << "请输入k值:"; cin >> k; } void Output(int **a, int n) { for (int i = 1; i <= n; ++i) { for (int j = 1; j <= n; ++j) cout << a[i][j] << " "; cout << endl; } } void Table(int k, int n, int **a) { for (int i = 1; i <= n; ++i) a[1][i] = i;//设置日程表第一行 int m = 1; for (int s = 1; s <= k; ++s) { n /= 2; // for (int t = 1; t <= n; ++t) { for (int i = m + 1; i <= 2 * m; ++i) for (int j = m + 1; j <= 2 * m; ++j) { a[i][j + (t - 1) * m * 2] = a[i - m][j - m + (t - 1) * m * 2]; a[i][j - m + (t - 1) * m * 2] = a[i - m][j + (t - 1) * m * 2]; } } m *= 2; } } /* m 为了设置每次填充时的起始位置 ;将原问题划分为 K 步骤解决,S 加以控制步骤的顺序; 将每步骤划分为 (n /= 2) 部分,t 控制每部分的初始化顺序; 将(t-1)*m*2 视为每次跨的步距, 每次的起始坐标(i, j)是(i, j)从初始位置(1, 1),i 下移 m, j 右移 m 后得到的, 若k = 3, 则Table()内 s = {1, 2, 3}; n = {4, 2, 1}; m = {1, 2, 4}; 为对角互相初始化的 推导式提供解释。 */