1 条题解

  • 0
    @ 2025-8-24 22:11:00

    自动搬运

    查看原文

    来自洛谷,原作者为

    avatar 2011hym
    暴力占据大脑,打表代替思考 | 寒鸦栖枯地,拿分靠暴力 | 空山不见人,爆0就红温

    搬运于2025-08-24 22:11:00,当前版本为作者最后更新于2025-07-10 22:02:55,作者可能在搬运后再次修改,您可在原文处查看最新版

    自动搬运只会搬运当前题目点赞数最高的题解,您可前往洛谷题解查看更多

    以下是正文


    前言

    非常非常经典的递归题目,还是我第一个 A 掉的黄题。

    当时我们机房还有人管它叫赤兔战俘

    解题思路

    显然若将目标矩阵平分为 44 个小矩阵,左上角的人一定会被赤兔赦免。

    注意递归的要素:

    • 函数功能
    • 结束条件
    • 问题分解

    那么套用到此题上呢?

    函数功能

    此函数的功能显然是判断矩阵中有谁会被赦免,这是很明确的目标。

    结束条件

    因为题目中给出的就是 2n×2n2^n\times 2^n 的矩阵,这也保证了最后一定能被划分为多个 2×22\times 2 的矩阵。

    故而终止条件就是划分到只剩下 2×22\times 2

    问题分解

    更不用说了,直接对半分。

    总体思路

    在每次递归中:

    • 如果当前边长为 22,直接将左上角的元素置为 00,然后结束。
    • 否则,将当前矩阵分成四个子矩阵:
      • 左上角的子矩阵全部设为 00
      • 左下、右下、右上的子矩阵依次递归调用函数。

    代码实现

    #include <bits/stdc++.h>
    using namespace std;
    int n,o=1,a[1145][1145];
    void dfs(int x,int l,int q){//三个参数意思分别是边长,以左上角为坐标原点的行数与列数。
    	if(x==2){
    		a[l][q]=0;
    		return;
    	}
    	for(int i=l;i<=l+x/2-1;i++){
    		for(int j=q;j<=q+x/2-1;j++){
    			a[i][j]=0;
    		}
    	}
    	dfs(x/2,l+x/2,q);
    	dfs(x/2,l+x/2,q+x/2);
    	dfs(x/2,l,q+x/2);
    }
    int main(){
        ios::sync_with_stdio;
        cin.tie(0);
        cout.tie(0);
    	cin>>n;
    	for(int i=1;i<=n;i++){
    		o*=2;
    	}
    	for(int i=1;i<=o;i++){
    		for(int j=1;j<=o;j++){
    			a[i][j]=1;
    		}
    	}
    	dfs(o,1,1);
    	for(int i=1;i<=o;i++){
    		for(int j=1;j<=o-1;j++){
    			cout<<a[i][j]<<" ";
    		}
    		cout<<a[i][o]<<endl;
    	}
    	return 0;
    }
    
    • 1

    信息

    ID
    4430
    时间
    1000ms
    内存
    125MiB
    难度
    3
    标签
    递交数
    0
    已通过
    0
    上传者