Question: Here is a 3*3 flip template. The dark part indicates the flip, and the light part remains unchanged. Then you can flip all the blocks in the r * C rectangle according to the template. The minimum output step.
Idea: I think a little bit better. Each block is flipped once at most, and the result of the flipped twice is the same. In this way, you can search, which is about 2 ^ 25 and Will time out. Consider pruning. For each flip, only a few blocks close to the block will be affected. That is to say, if there are no bright blocks before the block goes up to 2nd rows, no matter what happens afterwards, it will not be completely bright, because the subsequent blocks will not affect the previous ones at all.
The status can be represented in binary format. Code writing is messy.
#include<cstdio>#include<cstdlib>#include<queue>#include<cstring>#include<algorithm>using namespace std;int n,m,ans;bool ok[10][10];bool judge(int x,int y){ return 0<=x&&x<n&&0<=y&&y<m;}int flip(int state,int p){ bool st[10][10]= {0}; for(int i=0; i<n*m; ++i) if(state&(1<<i)) st[i/m][i%m]=true; else st[i/m][i%m]=false; int x=p/m,y=p%m; if(ok[0][0]&&judge(x-1,y-1)) st[x-1][y-1]=!st[x-1][y-1]; if(ok[0][1]&&judge(x-1,y)) st[x-1][y]=!st[x-1][y]; if(ok[0][2]&&judge(x-1,y+1)) st[x-1][y+1]=!st[x-1][y+1]; if(ok[1][0]&&judge(x,y-1)) st[x][y-1]=!st[x][y-1]; if(ok[1][1]&&judge(x,y)) st[x][y]=!st[x][y]; if(ok[1][2]&&judge(x,y+1)) st[x][y+1]=!st[x][y+1]; if(ok[2][0]&&judge(x+1,y-1)) st[x+1][y-1]=!st[x+1][y-1]; if(ok[2][1]&&judge(x+1,y)) st[x+1][y]=!st[x+1][y]; if(ok[2][2]&&judge(x+1,y+1)) st[x+1][y+1]=!st[x+1][y+1]; int res=0; for(int i=0; i<n; ++i) for(int j=0; j<m; ++j) if(st[i][j]) res=res|(1<<(i*m+j)); return res;}char g[10][10];int bitcount(int state){ int cnt=0; for(int i=0; i<n*m; ++i) if(state&(1<<i)) cnt++; return cnt;}bool check(int state,int p){ for(int i=0; i<p; ++i) if(!(state&(1<<i))) return false; return true;}void dfs(int cur,int state,int use){ if(cur>=n*m) { if(state==(1<<m*n)-1) { if(ans==-1||bitcount(use)<bitcount(ans)) ans=use; } return ; } int x=cur/m,y=cur%m; if(x>=2&&!check(state,m*(x-1))) return; dfs(cur+1,flip(state,cur),use|(1<<cur)); dfs(cur+1,state,use);}int main(){ int kase=0; while(scanf("%d%d",&n,&m)&&!(!n&&!m)) { ans=-1; for(int i=0; i<3; ++i) { scanf("%s",g[i]); for(int j=0; j<3; ++j) ok[i][j]=(g[i][j]==‘*‘); } printf("Case #%d\n",++kase); dfs(0,0,0); if(ans==-1) puts("Impossible."); else { bool fir=false; for(int i=0; i<n*m; ++i) if(ans&(1<<i)) if(fir) printf(" %d",i+1); else { fir=true; printf("%d",i+1); } printf("\n"); } } return 0;}/*5 3...***...*/View code