剪纸除法



问题PRO_7_4

 

如下一样有多个正方形格子构成的正方形模样的纸张,每个正方形涂着01。按照固定的规则对给出的纸张进行裁剪。想制作多种大小的涂着01的正方形模样彩纸。

面纸张的大小为N×N(N= ,k 1以上 7以下的自然数),裁剪规则如下所示:

一面纸张,如果没有涂着同样的颜色时,按照横和竖的方向剪中间部分,分成四张同样大小为的彩纸。对分成的各纸张 I,II,III,IV也要跟前面一样,如果没有涂着同样的颜色,就分成四张同样大小的彩纸。通过这样的过程,反复的进行裁剪,裁到纸张只涂着01,或者纸张已成一个格子不能再裁剪。

当给出纸张的长度N和每个正方形格子的颜色(01)时,请求一下裁剪的块中涂着0的彩纸和涂着 1的彩纸个数各个为多少的程序。

 

 

 

 

 

 

输入

第一行给出纸张的长度 NN 2,4,8,16,32,64,128中的一个。彩纸的每个横向正方形格子会从上开始按顺序从第二行给到最后一行。

每个数字之间都会有一个空格。

输出

第一行输出裁剪的彩纸中,涂着 0的彩纸个数,

第二行输出裁剪的彩纸中,涂着1的彩纸个数。

输入案例

8

1 1 0 0 0 0 1 1

1 1 0 0 0 0 1 1

0 0 0 0 1 1 0 0

0 0 0 0 1 1 0 0

1 0 0 0 1 1 1 1

0 1 0 0 1 1 1 1

0 0 1 1 1 1 1 1

0 0 1 1 1 1 1 1

输出案例

9

7

 

 

 

 

 

 

 

 

 

 

 

#include<iostream>

#include<fstream>

using namespace std;

#define MAX 1000

 

int a[MAX][MAX];

int b[2];

 

void dq(int x1,int y1,int x2,int y2){

   int i,j;

   int imsi;

   bool flag=1;

   imsi=a[x1][y1];

   for(i=x1;i<x2;i++){

       for(j=y1;j<y2;j++){

           if(a[i][j]!=imsi)

                flag=false;

       }

    }

   if(flag)

    {

       b[imsi]++;

       return;

    }

   dq(x1,y1,(x1+x2)/2,(y1+y2)/2);

   dq((x1+x2)/2,y1,x2,(y1+y2)/2);

   dq(x1,(y1+y2)/2,(x1+x2)/2,y2);

   dq((x1+x2)/2,(y1+y2)/2,x2,y2);

}

 

int main(){

   ifstream in;

   in.open("input.txt");

   int n,i,j;

   cin >> n;

   for(i=0;i<n;i++){

       for(j=0;j<n;j++){

           cin >> a[i][j];

       }

    }

   dq(0,0,n,n);

   cout << b[0] << endl << b[1];

   return 0;

}

#include<cstdio>

 

const int maxn = 128+1;

 

int n,r0=0,r1=0;

int c[maxn][maxn];

 

void calc(int rw,int cl,int k ){

        

         intt = 0;

         for(inti=rw;i<rw+k;i++){

                          for(intj=cl;j<cl+k;j++){

                                   t+=c[i][j];       

                          }      

         }

         if(t==0)r0++;

         elseif(t==k*k) r1++;

        

         else{

                  calc(rw,cl,k/2);

                  calc(rw,cl+k/2,k/2);

                  calc(rw+k/2,cl,k/2);

                  calc(rw+k/2,cl+k/2,k/2);

         }

         return;

        

}

int main(){

        

         scanf("%d",&n);

 

         for(inti=1;i<=n;i++){

                  for(intj=1;j<=n;j++){      

                          scanf("%d",&c[i][j]);

                  }

         }

        

         calc(1,1,n);

         printf("%d\n",r0);

         printf("%d\n",r1);

         return0;

}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值