一二三四五 上山打老虎

POJ1753-Flip Game

题目链接:https://ac.nowcoder.com/acm/problem/106350
题意:有个4x4的棋盘,棋盘上黑子翻过来是白子,白子翻过来是黑子,每翻一个子,其上,下,左,右共五个子都会对应翻过来,给出当前状况,问至少翻几个子会使整个棋盘都是一个颜色。

思路1:直接dfs深搜 O(216)

#include<iostream>

using namespace std;
char a[5][5];
int m[10][10]={0};
int ans=20;
//方法1:深搜
void dfs(int x,int y,int num){
    if(x==1&&y==5){
    int res=0;
    for(int i=1;i<=4;i++)
        for(int j=1;j<=4;j++)
            res+=m[i][j];
        if(res==0||res==16)ans=min(ans,num); //判断只需要看一下是否都为0或者都为1
       // cout<<res<<endl;
        return ;
    }
    int nx=x+1,ny=y;//下一跳
    if(nx==5){
        nx=1;
        ny++;
    }
    //t
    m[x][y]^=1;
    m[x+1][y]^=1;
    m[x][y+1]^=1;
    m[x-1][y]^=1;
    m[x][y-1]^=1;
    dfs(nx,ny,num+1);
    //f
    m[x][y]^=1;
    m[x+1][y]^=1;
    m[x][y+1]^=1;
    m[x-1][y]^=1;
    m[x][y-1]^=1;
    dfs(nx,ny,num);
}
int main (){
    for(int i=0;i<4;i++)
        cin>>a[i];
    for(int i=0;i<4;i++)
    for(int j=0;j<4;j++){
        if(a[i][j]=='b')
            m[i+1][j+1]=1;
    }
    dfs(1,1,0);
    if(ans==20)cout<<"Impossible";
    else cout<<ans<<endl;


return 0;
}

思路2:二进制枚举,枚举0~(216-1)表示每个子的情况

待补充

思路3:枚举第一行,第一行的选择能使第一行全为一个色,则其余行的选择是一定的,譬如经典关灯问题,适用于大数据;

待补充
posted @ 2021-01-19 18:36  abestxun  阅读(39)  评论(0)    收藏  举报