题目背景
借助反作弊系统,一些在月赛有抄袭作弊行为的选手被抓出来了!
题目描述
现有 2n×2n (n≤10) 名作弊者站成一个正方形方阵等候 kkksc03 的发落。kkksc03 决定赦免一些作弊者。他将正方形矩阵均分为 4 个更小的正方形矩阵,每个更小的矩阵的边长是原矩阵的一半。其中左上角那一个矩阵的所有作弊者都将得到赦免,剩下 3 个小矩阵中,每一个矩阵继续分为 4 个更小的矩阵,然后通过同样的方式赦免作弊者……直到矩阵无法再分下去为止。所有没有被赦免的作弊者都将被处以棕名处罚。
给出 n,请输出每名作弊者的命运,其中 0 代表被赦免,1 代表不被赦免。
输入格式
一个整数 n。
输出格式
2n×2n 的 01 矩阵,代表每个人是否被赦免。数字之间有一个空格。
输入输出样例
输入 #1复制
3
输出 #1复制
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
思路
当n=1时,可以得到
0 1
1 1
这是最小且满足题意的矩阵;
分析n=i(i=2,3,…)矩阵可以得到,所有的矩阵都是通过上面的矩阵和0矩阵得出
由于数据较大,输出时还必须加上快速输出PrintWriter
AC代码
import java.io.BufferedWriter;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.util.Scanner;
/**
*@Title P5461赦免战俘.java
*@description TODO
*@time 2020年10月11日
*@author Baisu
*@version 1.0
*/
public class P5461赦免战俘 {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
PrintWriter pw = new PrintWriter(new BufferedWriter(new OutputStreamWriter(System.out)));
int n = sc.nextInt();
int[][] t = new int [(int) Math.pow(2, n)][(int) Math.pow(2, n)];
t[0][0] = 1;
t[0][1] = 1;
t[1][0] = 1;
t[1][1] = 0;
for(int i=1; i<n; i++) {
// 右上
for(int j=0; j<(int)Math.pow(2, i); j++) {
for(int k=(int)Math.pow(2, i); k<(int)Math.pow(2, i+1); k++) {
t[j][k] = t[j][k-(int)Math.pow(2, i)];
}
}
// 左下
for(int j=(int)Math.pow(2, i); j<(int)Math.pow(2, i+1); j++) {
for(int k=0; k<(int)Math.pow(2, i); k++) {
t[j][k] = t[j-(int)Math.pow(2, i)][k];
}
}
// 右下
for(int j=(int)Math.pow(2, i); j<(int)Math.pow(2, i+1); j++) {
for(int k=(int)Math.pow(2, i); k<(int)Math.pow(2, i+1); k++) {
t[j][k] = 0;
}
}
}
// 反向输出
for(int i=(int) Math.pow(2, n)-1; i>=0; i--) {
for(int j=(int) Math.pow(2, n)-1; j>=0; j--) {
pw.print(t[i][j]+" ");
}
pw.println();
}
pw.flush();
}
}