【深基7.例8】赦免战俘 · 教师题解

【深基7.例8】赦免战俘

解题思路

把行列从 0 编号。每次四分对应检查行、列编号的同一二进制位;两者该位均为 0,说明进入了左上区域,应被赦免。只有每一位至少有一个 1 的位置不被赦免,即 (i | j) == 2^n-1。

正确性说明

每层的左上象限恰好对应当前行位和列位同时为 0。一旦有这种层级,该位置被赦免;所有层级都不存在这种情况时才保留 1。按位或恰好判定这一条件。

易错点

编号从 0 开始;按位或是 |,不要写成逻辑或 ||。

复杂度

边长 N=2^n,时间 O(N²),额外空间 O(1)。

参考代码(C++11)

#include <bits/stdc++.h>
using namespace std;

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    int n;
    cin >> n;
    int N = 1 << n;
    for (int i = 0; i < N; i++) {
        for (int j = 0; j < N; j++) {
            if (j)
                cout << " ";
            cout << ((i | j) == N - 1 ? 1 : 0);
        }
        cout << "\n";
    }
    return 0;
}
返回题目