P5461 赦免战俘
题目简介
现有 2 n ∗ 2 n 2^{n} * 2^{n} 2n∗2n (n<=10) 名作弊者站成一个正方形方阵等候 kkksc03 的发落。kkksc03 决定赦免一些作弊者。他将正方形矩阵均分为 4 个更小的正方形矩阵,每个更小的矩阵的边长是原矩阵的一半。其中左上角那一个矩阵的所有作弊者都将得到赦免,剩下 3 个小矩阵中,每一个矩阵继续分为 4 个更小的矩阵,然后通过同样的方式赦免作弊者……直到矩阵无法再分下去为止。所有没有被赦免的作弊者都将被处以棕名处罚。
给出 n,请输出每名作弊者的命运,其中 0 代表被赦免,1 代表不被赦免。
输入格式
一个整数n
输出格式
2 n ∗ 2 n 2^{n} * 2^{n} 2n∗2n 的01矩阵代表每个人是否被赦免。数字之间有一个空格。
#include<bits/stdc++.h>
#include<algorithm>
#define gc ch=getchar()
#define ps puts("")
#define pc putchar(32)
#define INF 0x3f3f3f3f
using namespace std;
const int N = 1e4+10;
template <class T>void read(T &s){
s=0;T f=1;char gc;
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;gc;}
while(ch<='9'&&ch>='0'){s=s*10+ch-'0';gc;}
s*=f;
}
template <class T>void put(T s){
if(s<0)s=-s,putchar('-');
if(s>9)put(s/10);
putchar(s%10+'0');
}
int qpow(int a,int n){
if(n==0) return 1;
else if(n%2==1) return qpow(a,n-1)*a;
else{
int temp=qpow(a,n/2);
return temp*temp;
}
}
char maps[N][N];
void dfs(int n,int x,int y){
//分割的矩边长 起始的矩阵内x,y坐标
if(n==2){
maps[x][y]='0';
return ;
}//如果边长只剩2了 把起始xy(即此时左上角)所在的格子"赦免"即可
for(int i=x;i<=x+n/2-1;i++)
for(int j=y;j<=y+n/2-1;j++)
maps[i][j]='0';
//将分割后的矩阵 左上角1/4矩阵赦免
dfs(n/2,x+n/2,y);
//分割后的右上1/4
dfs(n/2,x+n/2,n/2+y);
//分割后的右下1/4
dfs(n/2,x,n/2+y);
//分割后的左下1/4
}
int main(){
memset(maps,'1',sizeof(maps));
int m;
read(m);
int n=qpow(2,m);
dfs(n,1,1);
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
cout<<maps[i][j];
if(j<n) pc;
}
ps;
}
return 0;
}