P5461 赦免战俘

题目传送门

#include <bits/stdc++.h>

using namespace std;
const int N = 1100;
int a[N][N];

/**递归经典题
1、默认二维数组全是0,可以理解为默认都被赦免,如果找到不被赦免的,需要标识为1.
2、看到2^n之类的题,一般是采用递归方法。
3、递归肯定要有出口,出口的判定是极限值,就是只有一个单元时,怎么处理。
 本题就是n=0,表示区域只有一个人,无法继续分割,此时此人需要不被赦免。
4、左上角被赦免,其它三个小矩阵,也是一样的逻辑,所以可以重复递归使用cal.
5、递归的参数,就是左上角的开始坐标x,y,和边长2^n
6、其它三个小矩阵,需要计算出左上角的坐标值,这个需要使用画图通过数学来推导出来。
7、2^n用C++描述,就是 1<<n,位运算的技巧。同样,2^(n-1)就是1<<(n-1),因为<<运算的优先级没有-号高,也可以写成 1<<n-1
*/
void cal(int x, int y, int n) {
    if (n == 0) a[x][y] = 1;
    else {
        cal(x + (1 << (n - 1)), y, n - 1);//左下角
        cal(x, y + (1 << (n - 1)), n - 1);//右上角
        cal(x + (1 << (n - 1)), y + (1 << (n - 1)), n - 1);//右下角
    }
}

int main() {
    int n;
    cin >> n;
    //开始计算最大的矩阵
    cal(0, 0, n);
    //输出
    for (int i = 0; i < (1 << n); i++)
        for (int j = 0; j < (1 << n); j++)
            //这个换行符有点意思
            printf("%d%c", a[i][j], j == (1 << n) - 1 ? '\n' : ' ');
    return 0;
}
原文地址:https://www.cnblogs.com/littlehb/p/15575604.html