循环比赛

问题描述

     设有n=2^k个运动员要进行网球循环赛。现要设计一个满足以下要求的比赛日程表:

     (1)每个选手必须与其他n-1个选手各赛一次;
     (2)每个选手一天只能参赛一次;
     (3)循环赛在n-1天内结束;
     (4)每个元素占用空间为四个字符; 

     请按此要求将比赛日程表设计成有n行和n-1列的一个表。在表中的第i行,第j列处填入第i个选手在第j天所遇到的选手。其中1≤i≤n,1≤j≤n-1。8个选手的比赛日程表如下表:

选手|对手|时间第一天第二天第三天
1234
2143
3412
4321

思路:

通过这个表格很难给出结果,因此分治法;可以先选两个选手:

                                                         1  |  2 
                                                         2  |  1

同理,四个选手:

                                                         1    2   |  3   4
                                                         2    1   |  4   3 
                                                         3    4   |  1   2 
                                                         4    3   |  2   1

可看出:矩阵右上角与左下角对称,以最初的1×1方阵按上述规则生成2×2方阵,然后生成4×4方阵,直到完成整个循环比赛表为止,用变量h表示当前方阵的大小,也就是要生成下一个方阵的一半;

总是对以某三点组成的正方形角逐步更新;

#include<cstdio>
#include<iostream>
#include<iomanip>
#include<cstdlib>
using namespace std;

int pow(int x,int n) {
	int res = 1;
	for(int i = 0; i < n; i++) res *= x;
	return res;
}

int main() {
	int m, n, h = 1;
	int a[35][35];
	a[1][1] = 1;
	cin >> m;
	n = pow(2, m);
	do {
		//cout << "******" <<endl;
		for(int i = 1; i <= h; i++) {
			//cout << "***for1***  " << i <<endl;
			for(int j = 1; j <= h; j++) {
				//cout << "***for2***  " << j <<endl;
				a[i][j + h] = a[i][j] + h;    //构造右上角方阵
				a[i + h][j] = a[i][j + h];    //构造左下角方阵
				a[i + h][j + h] = a[i][j];    //构造右下角方阵
			}
		}
		h *= 2;
	}while(!(h == n));
	for(int i = 1; i <= n; i++) {
		for(int j = 1; j <=n; j++)
		cout << setw(4) << a[i][j];
		cout << endl;
	}
	return 0;
} 

setw()函数是控制元素所占空间大小,头文件为iomanip

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值