POJ 3279 Fliptile


3279

非常规DFS/BFS:若不考虑约束条件搜索,算法复杂度指数级

#include
#include
#include
#include
#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=0&&y<N){
                tmp_grid[x][y] = (tmp_grid[x][y]+1)%2;
            }
        }
    }
}
bool solve(){
    for(int i=1;i){
        for(int j=0;j){
            if(tmp_grid[i-1][j]==1){
                flip[i][j]=1;
                Flip(i,j);
            }
        }
    }
    for(int j=0;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){
        for(int j=0;j){
            cin>>grid[i][j];
        }
    }
    // 只需枚举第一行的所有状态!下面各行依次是否flip会被唯一确定。
    // 不考虑这约束条件,对flip整个空间搜索不可以!
    for(int f1=0;f1<(1<// 压缩后的状态f1(第一行)
        memcpy(tmp_grid,grid,sizeof(grid));
        memset(flip,0,sizeof(flip));
        num = 0;

        for(int j=0;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){
            for(int j=0;j){
                if(j==0) printf("%d",ans[i][j]);
                else printf(" %d",ans[i][j]);
            }
            printf("\n");
        }
    }
}
oj