循环比赛题解

    技术2022-07-11  131

    前言

    这道题一本通上有,但是那上面while的写法好像会炸,所以写一个递归的做法.

    题目链接:循环比赛


    观察样例,我们可以发现每2的n次方的方阵总会有右上与左下相同,左上与右下相同,并且右边的方阵对应位置的元素等于左边的对应位置的元素+当前左边方阵的边 长

    所以我们可以每次构建从a[i][j]向下(i+1,j),向右(i,j+1),向右下(i+1,j+1)的元素,当循环的次数等于m时就返回。

    代码:

    #include<cstdio> #include<cmath> using namespace std; int m,n,a[3005][3005],ban=1,M=1; void find(int ban) { if(ban==1)//初始元素 { a[0][0]=1; } if(ban==n)//已经构造完毕 { return;//返回 } for(int i=0;i<ban;i++) { for(int j=0;j<ban;j++) { a[i][j+ban]=a[i][j]+ban; a[i+ban][j]=a[i][j]+ban; a[i+ban][j+ban]=a[i][j];//上面三条都是根据规律所写的式子 } } find(ban*2);//扩倍构造 } int main() { scanf("%d",&m); n=1<<m; ban=1; find(1);//从第1个元素开始 for(int i=0;i<n;i++) { for(int j=0;j<n;j++) { printf("%d ",a[i][j]); } printf("\n"); } return 0; }

    关于证明

    感觉这道题不能用很严谨的数学方法证明,但是可以知道每个方阵的第一个人都是先与自己临近的人比赛,当轮完一轮后又跟下一个方阵的未比赛过的人比。所以按照流程,规律应该就是这样


    Processed: 0.008, SQL: 9