【题意】一个m*n的01矩阵,每次点击(x,y),那么她的上下左右以及本身就会0变1,1变0,问把矩阵变成全0的,最小需要点击多少步。
【分析】只需要枚举第一行的状态即可,后面的状态都可以根据第一行直接推出来,还要注意这题还有不存在的情况,详见代码!
【AC代码】
#include <map>
#include <set>
#include <queue>
#include <cstdio>
#include <cstring>
#include <iostream>
using namespace std;
int n,m;
int maze[15][15];
int ans[15][15];
int b[15][15];
void press(int x,int y){
ans[x][y] = 1;
b[x][y] = 1-b[x][y];
if(x>0) b[x-1][y] = 1-b[x-1][y];
if(x<n-1) b[x+1][y] = 1-b[x+1][y];
if(y>0) b[x][y-1] = 1-b[x][y-1];
if(y<m-1) b[x][y+1] = 1-b[x][y+1];
}
int main(){
while(~scanf("%d%d",&n,&m)){
for(int i=0; i<n; i++){
for(int j=0; j<m; j++){
scanf("%d",&maze[i][j]);
}
}
bool flag=false;
for(int s=0; s<(1<<m); s++){
memset(ans,0,sizeof(ans));
for(int i=0; i<n; i++){
for(int j=0; j<m; j++){
b[i][j] = maze[i][j];
}
}
for(int i=0; i<m; i++){
if(s&(1<<i)) press(0,i);
}
for(int i=1; i<n; i++){
for(int j=0; j<m; j++){
if(b[i-1][j]==1) press(i,j);
}
}
bool *** = true;
for(int i=0; i<m; i++){
if(b[n-1][i]==1) *** = false;
}
if(***){
flag = true;
for(int i=0; i<n; i++){
for(int j=0; j<m-1; j++){
printf("%d ",ans[i][j]);
}
printf("%d\n",ans[i][m-1]);
}
break;
}
}
if(flag==false)
puts("IMPOSSIBLE");
}
return 0;
}