洛谷 :P5461 赦免战俘(题解)

P5461 赦免战俘
题目背景

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

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

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

一个整数 nnn。
输出格式

2n×2n2^n \times 2^n2n×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

#include 
#include 
#include 
int m[1025][1025];
void fun(int a,int b,int c,int d);
int main()
{
    int n,k,i,j;
    scanf("%d",&n);
    k=pow(2,n);//求2的n次方;
    for(i=1;i<=k;i++)
    for(j=1;j<=k;j++)//双循环将m数组全部初始化为1;
    m[i][j]=1;
    fun(1,1,k,k);
    for(i=1;i<=k;i++)
    {
      for(j=1;j<=k;j++)//输出m数组;
      {
        printf("%d",m[i][j]);
        if(j!=k)
        printf(" ");
      }
      if(i!=k)
      printf("\n");
    }
    return 0;
}
void fun(int a,int b,int c,int d)//(a,b)为最左上角的坐标(c,d)为最右下角的坐标;
{//用这两个点的坐标来定位相应的矩阵方位;
    int i,j;
    for(i=a;i<=(a+c)/2;i++)//将左上角的值全部赋为1;
    for(j=b;j<=(b+d)/2;j++)
    m[i][j]=0;
    if(a==(a+c)/2)//如果此表达式成立即为该矩阵为最小的4*4矩阵,无需执行后续操作;
    return;
    fun((c+a+1)/2,b,c,(d+b-1)/2);//对右上角的矩阵进行操作;
    fun(a,(d+b+1)/2,(c+a-1)/2,d);//对左下角的矩阵进行操作;
    fun((c+a+1)/2,(d+b+1)/2,c,d);//对右下角的矩阵进行操作;
}

你可能感兴趣的:(矩阵,算法,c语言)