杂码系列之 Annoying painting tool hdoj 1801

110 篇文章 0 订阅
8 篇文章 0 订阅

/*
Annoying painting tool

http://acm.hdu.edu.cn/showproblem.php?pid=1801

Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 321    Accepted Submission(s): 227


Problem Description
Maybe you wonder what an annoying painting tool is? First of all, the painting tool we speak of supports only black and white. Therefore, a picture consists of a rectangular area of pixels, which are either black or white. Second, there is only one operation how to change the colour of pixels:

Select a rectangular area of r rows and c columns of pixels, which is completely inside the picture. As a result of the operation, each pixel inside the selected rectangle changes its colour (from black to white, or from white to black).

Initially, all pixels are white. To create a picture, the operation described above can be applied several times. Can you paint a certain picture which you have in mind?

 

Input
The input contains several test cases. Each test case starts with one line containing four integers n, m, r and c. (1 ≤ r ≤ n ≤ 100, 1 ≤ c ≤ m ≤ 100), The following n lines each describe one row of pixels of the painting you want to create. The ith line consists of m characters describing the desired pixel values of the ith row in the finished painting ('0' indicates white, '1' indicates black).

The last test case is followed by a line containing four zeros.

 

Output
For each test case, print the minimum number of operations needed to create the painting, or -1 if it is impossible.

 

Sample Input
3 3 1 1
010
101
010
4 3 2 1
011
110
011
110
3 4 2 2
0110
0111
0000
0 0 0 0
 

Sample Output
4
6
-1
 

Source
HDOJ 2007 Summer Exercise(1)
*/

 题目大意:

一个N×M的图片(N,M<100),每个点只有01两种状态。现在有一个R×C的画图工具(R<N,C<M),画一次能将矩形区域内的所有点状态翻转。初始时所有点都是0,现在给出一种目标图片,问最少需要几笔能画出来。

分析:

超级构造法

首先限制条件:

1、画笔在同一位置最多能画一次。(同一位置画两次<=>不画)。

2、考虑最左上角的一点,只有当画笔在最左上角的时候才能改变状态。

    若该点和目标图片一致,则不用画;

     否则需要在这个点的地方画一笔,同时将矩形其他点的状态翻转。

3、然后考虑左上角的第二个点,同样地,由于影响该点的画笔只有两个位置,而第一个位置刚才已经确定了,根据该点的状态也能确定是否要在第二个点画一笔……

4、依次确定从左上到右下的每一个点,

    若该点与目标图片不一致,则必须在该点画一笔;否则不用。
*/
#include<cstdio>
#include<string.h>
#include<stdlib.h>
char num1[100][100];
bool num[100][100];
bool jude[100][100];

int main()
{
 
 int n,m,r,c;
 
 while(scanf("%d%d%d%d",&n,&m,&r,&c),(n||m||r||c))
 {
   getchar();
   int i,j;
   memset(num,0,sizeof(num));
       for(i=0;i<n;i++)   //若在此处直接用int数组或char数组单个输入num[i][j],结果是出不来的,试了一上午尴尬
  {
            scanf("%s",num1[i]);
            for(j=0;j<m;j++)
      if(num1[i][j]=='1')
        num[i][j]=1;
        else
          num[i][j]=0;
        }

      memset(jude,0,sizeof(jude));
     int count=0,p=0,q=0;
    
    for(i=0;i<n-(r-1);i++)
     for(j=0;j<m-(c-1);j++)
      if(num[i][j]!=jude[i][j])
       {
       count++;
              for(p=0;p<r;p++)
                for(q=0;q<c;q++)
               jude[p+i][q+j]=!jude[p+i][q+j];
     
    }
  
    int temp=1;
    for(i=n-1;i>=0;i--)
       for(j=m-1;j>=0;j--)
          if(num[i][j]!=jude[i][j]&&temp)
              temp=0;
             
       if(temp)
     printf("%d\n",count);
     else
      printf("-1\n"); 
                  
 }
 return 0;
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值