【深基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;
}