POJ 3279 Fliptile
3279
非常规DFS/BFS:若不考虑约束条件搜索,算法复杂度指数级
#include<iostream> #include<algorithm> #include<queue> #include<vector> #include<string.h> #include"limits.h" using namespace std; const int MAX_M=17; const int MAX_N=17; int M,N; int grid[MAX_M][MAX_N]; int tmp_grid[MAX_M][MAX_N];// modified grid int flip[MAX_M][MAX_N]; int num; int min_n=INT_MAX; int ans[MAX_M][MAX_N]; void Flip(int i,int j){// flip tmp_grid (rather than grid) if(flip[i][j]){ num++; int to[5][2]= {{0,0},{-1,0},{1,0},{0,-1},{0,1}}; // 易错点:习惯性用i,与外围i重名 for(int k=0;k<5;k++){ int x = i+to[k][0]; int y = j+to[k][1]; if(x>=0&&x<M && y>=0&&y<N){ tmp_grid[x][y] = (tmp_grid[x][y]+1)%2; } } } } bool solve(){ for(int i=1;i<M;i++){ for(int j=0;j<N;j++){ if(tmp_grid[i-1][j]==1){ flip[i][j]=1; Flip(i,j); } } } for(int j=0;j<N;j++){// 最后一行 if(tmp_grid[M-1][j]==1) return false; } return true; } int main(){ // memset,memcpy参数num的单位是bytes memset(grid,0,sizeof(grid)); scanf("%d %d",&M,&N); for(int i=0;i<M;i++){ for(int j=0;j<N;j++){ cin>>grid[i][j]; } } // 只需枚举第一行的所有状态!下面各行依次是否flip会被唯一确定。 // 不考虑这约束条件,对flip整个空间搜索不可以! for(int f1=0;f1<(1<<N);f1++){// 压缩后的状态f1(第一行) memcpy(tmp_grid,grid,sizeof(grid)); memset(flip,0,sizeof(flip)); num = 0; for(int j=0;j<N;j++){// f1状态解压 flip[0][j]=(f1>>(N-1-j)) & 1; Flip(0,j); } if(solve() && num<min_n){ min_n = num; memcpy(ans,flip,sizeof(ans)); } } if(min_n==INT_MAX) { printf("IMPOSSIBLE\n"); }else { for(int i=0;i<M;i++){ for(int j=0;j<N;j++){ if(j==0) printf("%d",ans[i][j]); else printf(" %d",ans[i][j]); } printf("\n"); } } }