P5461 赦免战俘

题目链接:https://www.luogu.com.cn/problem/P5461

又是一道眼高手低的题目,考察的是最基础的递归,然而我又错了

画个图方便理解

 很容易想到用递归,用递归的话,先考虑递归的边界,就是递归何时结束

对于一个正方形数组,首先将其分为四份,左上角那一块全部赦免,再依次递归其余三部分,当这个正方形数组的边长为2时,

就可以结束递归了。

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 const int N = 2048;
 4 int a[N][N];
 5 int n; //次方数
 6 int p = 1; //p = 2 ^ n
 7 void di(int x,int l,int q) { 
 8     //x为当前处理的正方形的边长
 9     //l、q分别为递归正方形的左上角的横、纵坐标
10     if (x == 2) { //递归边界
11         a[l][q] = 0; //赦免左上角
12         return;
13     }
14     for (int i = l; i <= l + x / 2 - 1; i++) {
15         for (int j = q; j <= q + x / 2 - 1; j++) {
16             a[i][j] = 0; //将左上方的正方形清零
17         }
18     }
19     di(x / 2, l + x / 2, q); //递归处理剩余的三个正方形,注意参数
20     di(x / 2, l + x / 2, q + x / 2); //递归处理剩余的三个正方形,注意参数
21     di(x / 2, l, q + x / 2); //递归处理剩余的三个正方形,注意参数
22 }
23 int main() {
24     cin >> n;
25     for (int i = 1; i <= n; i++) {
26         p *= 2; //计算正方形的边长
27     }
28     for (int i = 1; i <= p; i++) {
29         for (int j = 1; j <= p; j++) {
30             a[i][j] = 1; //1表示未赦免,0表示赦免
31         }
32     }
33     di(p, 1, 1); //开始递归
34     for (int i = 1; i <= p; i++) {
35         for (int j = 1; j <= p; j++) {
36             cout << a[i][j] << " ";
37         }
38         cout << endl;
39     }
40     return 0;
41 }

 

posted @ 2020-09-26 19:20  kyk333  阅读(232)  评论(0)    收藏  举报