记录一下人生中第二道提高-
题目背景
借助反作弊系统,一些在月赛有抄袭作弊行为的选手被抓出来了!
题目描述
现有x(n≤10) 名作弊者站成一个正方形方阵等候 kkksc03 的发落。kkksc03 决定赦免一些作弊者。他将正方形矩阵均分为 4 个更小的正方形矩阵,每个更小的矩阵的边长是原矩阵的一半。其中左上角那一个矩阵的所有作弊者都将得到赦免,剩下 3 个小矩阵中,每一个矩阵继续分为 4 个更小的矩阵,然后通过同样的方式赦免作弊者……直到矩阵无法再分下去为止。所有没有被赦免的作弊者都将被处以棕名处罚。
给出 n,请输出每名作弊者的命运,其中 0 代表被赦免,1 代表不被赦免。
输入格式
一个整数 n。
输出格式
x的 01 矩阵,代表每个人是否被赦免。数字之间有一个空格。
输入输出样例
输入
3
输出
0 0 0 0 0 0 0 1 0 0 0 0 0 0 1 1 0 0 0 0 0 1 0 1 0 0 0 0 1 1 1 1 0 0 0 1 0 0 0 1 0 0 1 1 0 0 1 1 0 1 0 1 0 1 0 1 1 1 1 1 1 1 1 1
分析
(本质是一道递推题,有很多种思路,作者用的模拟。第一次做的时候卡了很久,第二天才想通)
想法:由大正方形开始切割,直到成为单独的小正方形,停止迭代
1.开最大化数组,默认0,根据题意赋1,最后逆转0和1即可
2.square函数:i、j负责填满“大正方形”的内部 k、m负责定位“大正方形”(看代码有点绕 但把握住思想自己也能写出来)
3.输出时注意逆转0和1
AC代码
#include<bits/stdc++.h>
using namespace std;
int a[1800][1800]; //默认为0
void square(int n, int max) {
int i, j, p = pow(2, n - 1), x = max - n, k, m;
if (n == 0)
return;
else {
for (i = 1; i <= p; i++) { //i、j用来填满正方形
for (j = 1; j <= p; j++) {
for (k = 0; k <= pow(2,x); k++) { //k、m用来定位正方形
for (m = 0; m <= pow(2, x); m++) {
a[i + k * 2 * p][j + m * 2 * p] = 1; //标记为1
}
}
}
}
}
return square(n - 1, max); //递归“小一号”正方形 一直到单独的正方形
}
int main() {
int n, i, j;
cin >> n;
square(n, n);
for (i = 1; i <= pow(2, n); i++) {
for (j = 1; j <= pow(2, n); j++) {
if (a[i][j] == 0) //按题意逆转0和1
cout << "1 ";
else
cout << "0 ";
}
cout << endl;
}
return 0;
}
附上思考时手写笔记(仅供参考)