今天做一道相对简单的题。。
1.n=2^k个运动员进行网球循环赛,需要设计比赛日程表。每个选手必须与其他n-1个选手各比赛一次;每个选手每天只能比赛一次;循环赛一共进行n-1天。按此要求设计一张比赛日程表,该表有n行,n-1列,第i行j列为第i个选手第j天遇到的选手。
解题思路:
利用分治原理 从大的 日程表一直分;
1 2 3 4 5 6 7 8
2 1 4 3 6 5 8 7
3 4 1 2 7 8 5 6
4 3 2 1 8 7 6 5
5 6 7 8 1 2 3 4
6 5 8 7 2 1 4 3
7 8 5 6 3 4 1 2
8 7 6 5 4 3 2 1
右下角等于左上角,右上角等于左下角等于左上角的加上最大那个数。
写程序是需要注意 位运算的优先级比加减法还要低 一定要注意 不然会错。。。。。
用vector 写练习 vector 。
源程序:
#include <iostream>
#include <cmath>
#include <vector>
#include <iomanip>
using namespace std;
const int maxn = 1<<10;
int k;
vector<vector<int> > schd(maxn);
void print_schd() {
for(int i = 0; i < 1<<k; i++) {
for(int j = 0; j < 1<<k; j++)
cout << setiosflags(ios::left) << setw(3) << schd[i][j];
cout << endl;
}
}
void copy(int size) { //一定要记得 << 位运算的 优先级比 加 减 还要低*************************
for(int i = 0; i < 1<<size-1; i++)
for(int j = 0; j < 1<<size-1; j++) {
schd[i + (1<<size-1)][j + (1<<size-1)] = schd[i][j]; //右下角的copy左上角的
schd[i][j + (1<<size-1)] = schd[i][j] + (1<<size-1); //右上角的=左下角 = 旁边的加2^(size-1)
schd[i + (1<<size-1)][j] = schd[i][j] + (1<<size-1);
}
}
void dfs(int size) {
if(size == 2) {
copy(size);
return;
} else {
dfs(size-1);
copy(size);
}
}
int main() {
cin >> k;
for(int i = 0; i < maxn; i++) schd[i].resize(maxn);
schd[0][0] = schd[1][1] = 1;
schd[0][1] = schd[1][0] = 2;
dfs(k);
print_schd();
return 0;
}