循环比赛(详细分析:递推)

    技术2022-07-11  141

    题目描述 在修罗王和邪狼亡命天涯的同时,魔法学院一年一度的运动会正开的如火如荼。赛场上,业余评论员墨老师正在给观众做激情解说:“鬣狗群……咬住!咬住!鬣狗头子立功了!不要给斑马任何的机会!伟大的鬣狗!伟大的鬣狗头子!它继承了猛兽光荣的历史和传统!豹子、老虎、雄狮在这一刻灵魂附体!”

    呃,这个,我们不要管那些场上选手的绰号了,现在的问题是有某个项目的n个选手进行循环比赛,其中n=2^m,要求每名选手要与其他n-1名选手都赛一次。每名选手每天比赛一次,循环赛共进行n-1天,要求每天没有选手轮空。比赛时间表格如图所示(假定m=3)。 输入格式 为一个整数m,m≤5。

    输出格式 为n行n列的整型矩阵,即比赛表格。每个元素之间由空格隔开,行末无多余空格。(注意:无需文件输入输出!)

    样例

    样例输入 2

    样例输出 1 2 3 4 2 1 4 3 3 4 1 2 4 3 2 1

    题解 通过枚举能发现一个规律: 1 2 2 1

    1 2 3 4 2 1 4 3 3 4 1 2 4 3 2 1 ······

    把每一个矩阵分割成四个部分可以发现: m=1:

    1 2 2 1 第一部分: 1 第二部分: 2 第三部分: 2 第四部分: 1 m=2:

    1 2 3 4 2 1 4 3 3 4 1 2 4 3 2 1 第一部分: 1 2 2 1 第二部分: 3 4 4 3 第三部分: 3 4 4 3 第四部分: 1 2 2 1 ······ 第一部分,第四部分与第m-1个矩阵相同;

    第二部分,第三部分与第m-1个矩阵每个数加2^(m-1)相同;

    代码如下:

    #include<bits/stdc++.h> using namespace std; int main(){ int a,n=1,m[35][35]={}; m[1][1]=1; scanf("%d",&a); for(int k=1;k<=a;k++){ n=pow(2,k); for(int i=1;i<=n/2;i++){ for(int j=n/2+1;j<=n;j++){ m[i][j]=m[i][j-n/2]+n/2; } } for(int i=1;i<=n/2;i++){ for(int j=n/2+1;j<=n;j++){ m[j][i]=m[j-n/2][i]+n/2; } } for(int i=n/2+1;i<=n;i++){ for(int j=n/2+1;j<=n;j++){ m[i][j]=m[i-n/2][j-n/2]; } } } for(int i=1;i<=n;i++){ printf("%d",m[i][1]); for(int j=2;j<=n;j++){ printf(" %d",m[i][j]); } if(i!=n)printf("\n"); } }
    Processed: 0.009, SQL: 9