oj:https://vjudge.net/problem/CodeForces-1207B
题目大意:
给定两个矩阵,长n,宽m,大小一样。A矩阵中全部都是0,B矩阵由input进行输入,输入中包含1或0。给定我们一种操作,假设我们现在处于矩阵的x,y位置,那么这个操作会将A中的(x,y),(x+1,y),(x,y+1),(x+1,y+1)这个2*2的矩阵转换为1。注意坐标从1,1开始,1≤?<? and 1≤?<?。喊输出操作的个数和操作的为位置(x,y),注意,不要求操作次数最小。
input 3 3 1 1 1 1 1 1 0 1 1 output 3 1 1 1 2 2 2
千万要注意题目中的说的不要求操作次数最小,当时做这个题的时候以为是求最小操作次数,纠结了很久。
我们来分析,要将A变成B的样子,且每次操作的只能是一个2*2的矩阵,要求A和B操作之后一模一样。由于不限制操作次数,我们可以在B上划分2*2的矩阵,因为A操作只能操作2*2的矩阵,所以如果B中的某些1不能组成2*2的矩阵与周围的1,那说明操作也不可能得结果,所以我们只要划分出所有的2*2矩阵,对A中对应位置进行操作。最终判断A和B是否相同即可
代码实现:
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define max 51
int main() {
int map[max][max];
int cur[max][max];
int res[2500][2];
memset(cur,0,sizeof(cur));
int m,n;
scanf("%d %d",&n,&m);
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
scanf("%d",&map[i][j]);
}
}
int r = 0;
for(int i=1;i<n;i++){
for(int j=1;j<m;j++){
if(cur[i][j] == 1 && map[i][j] == 0){
printf("-1\n");
return 0;
}
if(check(map,i,j)){
fill(cur,i,j);
res[r][0] = i;
res[r++][1] = j;
}
}
}
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
if(cur[i][j] != map[i][j]){
printf("-1\n");
return 0;
}
}
}
printf("%d\n",r);
for(int i=0;i<r;i++){
printf("%d %d\n",res[i][0],res[i][1]);
}
return 0;
}
void fill(int d[max][max],int x,int y){
d[x][y] = 1;
d[x+1][y] = 1;
d[x][y+1] = 1;
d[x+1][y+1] = 1;
}
int check(int map[max][max],int x,int y){
if(map[x][y] == 1 && map[x+1][y] == 1 && map[x][y+1] == 1 &&
map[x+1][y+1] == 1){
return 1;
}
return 0;
}