P5461 赦免战俘

记录一下人生中第二道提高-

题目背景

借助反作弊系统,一些在月赛有抄袭作弊行为的选手被抓出来了!

题目描述

现有2^{n}x2^{n}(n≤10) 名作弊者站成一个正方形方阵等候 kkksc03 的发落。kkksc03 决定赦免一些作弊者。他将正方形矩阵均分为 4 个更小的正方形矩阵,每个更小的矩阵的边长是原矩阵的一半。其中左上角那一个矩阵的所有作弊者都将得到赦免,剩下 3 个小矩阵中,每一个矩阵继续分为 4 个更小的矩阵,然后通过同样的方式赦免作弊者……直到矩阵无法再分下去为止。所有没有被赦免的作弊者都将被处以棕名处罚。

给出 n,请输出每名作弊者的命运,其中 0 代表被赦免,1 代表不被赦免。

输入格式

一个整数 n。

输出格式

2^{n}x2^{n}的 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;
}

附上思考时手写笔记(仅供参考)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Achilles0705.

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值