循环赛日程表(分治)

本文介绍了一种使用分治策略生成循环赛日程表的方法,适用于1到2的n次方个参赛者。通过递归地将参赛者分为两半,直至剩下两个选手,简化了比赛日程的制定过程。文章提供了C++代码实现,展示了如何通过递归调用处理不同规模的参赛者数量。

题目:

时限:1000ms 内存限制:10000K  总时限:3000ms

描述

用分治算法生成循环赛日程表(1到2的n次方个人)

 

输入

一个小于等于7的正整数n

 

输出

循环赛日程表(1到2的n次方个人)

 

输入样例

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

我们采用分治策略,将所有的选手分为两半,n个选手的比赛日程表可以通过为n / 2个选手设计的比赛日程表来确定。递归的用一分为二的策略对选手进行分割,直到只剩下两个选手时,比赛日程表的制定就变得简单。这时只让两个选手进行比赛就可以。

在比赛安排中,左上角与左下角的2小块的分别为选手1到选手4 以及选手5 之选手8前3天的比赛日程。据此将左上角小块中的所有数字按其相对位置抄到右下角,将左下角小块的元素按其相对位置抄到右上角这样就安排好了选手1至选手4以及选手5至选手8在后4天的比赛日程。

#include <iostream>

using namespace std;

const int maxn = 10005;
int a[maxn][maxn];
void dfs(int length,int n)
{
    //初始正确;
    a[1][1] = 1;
    a[1][2] = 2;
    a[2][1] = 2;
    a[2][2] = 1;
    for(int k = 1;k <= n;k ++)
    {
        int tmp = length;
        length *= 2;
        for(int i = tmp + 1;i <= length;i ++)
        {
            for(int j = 1;j <= tmp;j ++)
            {
                a[i][j] = a[i - tmp][j] + tmp;
            }
        }
        for(int i = tmp + 1;i <= length;i ++)
        {
            for(int j = 1;j <= tmp;j ++)
            {
                a[i - tmp][j + tmp] = a[i][j];//左下角抄到右上角。
            }
        }
        for(int i = 1;i <= tmp;i ++)
            for(int j = 1;j <= tmp;j ++)
            {
                a[i + tmp][j + tmp] = a[i][j];//左上角抄到右下角。
            }
    }
}

int main()
{
    int n,k;
    cin >> n;
    k = 1 << n;
    dfs(2,n);
    for(int i = 1;i <= k;i ++)
    {
        for(int j = 1;j <= k;j ++)
        {
            cout << a[i][j];
            if(j == k)cout << endl;
            else cout <<" ";
        }
    }
    return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值