【题目描述】
设有N个选手进行循环比赛,其中N=2^M,要求每名选手要与其他N−1名选手都赛一次,每名选手每天比赛一次,循环赛共进行N−1天,要求每天没有选手轮空。
【输入】
输入:M。
【输出】
输出:表格形式的比赛安排表。一行各数据间用一个空格隔开。
【输入样例】
3
【输出样例】
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文章来源:https://www.toymoban.com/news/detail-418705.html
分析
可以发现规律,左上等于右下,右上等于左下,把整个大矩阵分成最小的一块,也就是1个1,然后慢慢再合并成一个大矩阵;看下zjt大佬的题解:1325:【例7.4】 循环比赛日程表
文章来源地址https://www.toymoban.com/news/detail-418705.html
#include<bits/stdc++.h>
using namespace std;
int a[1000][1000];
int m;
int main() {
std::ios::sync_with_stdio(false);
cin.tie(nullptr);
cin >> m;
a[1][1] = 1;
int d = 1;//扩展的数的差值,行列索引的差值
for (int k = 1; k <= m; ++k) {//在起点基础上再扩展m次
//根据已知的左上角 +d 来确定右上角
for (int i = 1; i <= d; i++) {//行(1,d)
for (int j = d + 1; j <= 2 * d; ++j) {//列(d+1,2d)
a[i][j] = a[i][j - d] + d;
}
}
//进行复制,将左上角复制给右下,右上复制给左下
//左上到右下(行列各加d)
for (int i = d + 1; i <= 2 * d; i++) {
for (int j = d + 1; j <= 2 * d; j++) {
a[i][j] = a[i - d][j - d];
}
}
//右上到左下(行+d,列1~d)
for (int i = d + 1; i <= 2 * d; i++) {
for (int j = 1; j <= d; j++) {
a[i][j] = a[i - d][j + d];
}
}
//进行下一次的扩展
d *= 2;
}
for (int i = 1; i <= pow(2, m); ++i) {
for (int j = 1; j <= pow(2, m); ++j) {
cout << a[i][j] << " ";
}
cout << endl;
}
return 0;
}
到了这里,关于1325:【例7.4】 循环比赛日程表——分治的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!