Problem : 翻棋子

Problem : 翻棋子

Description
有一个4*4的棋盘,放有16枚棋子。
每个棋子都是一面黑一面白,一开始有的黑面朝上,有的白面朝上。
下面是一个例子,这个例子用文字描述为:
bwbw
wwww
bbwb
bwwb
我们可以任选一个棋子,把它自己和它的相邻棋子(上下左右,如果有的话)翻面。
比如在例子中如果我们选第3行第1列的棋子翻面,布局就变成如下:
bwbw
bwww
wwwb
wwwb
题目
求出能把所有棋子都翻成白色或都黑色的最少的步数。

Input
4行每行4个字符,可能是b(黑)或w(白)

Output
一个数,最少步数。如果无解输出Impossible

Sample Input
bwbw
wwww
bbwb
bwwb
Sample Output
Impossible

#include<iostream>
using namespace std;
bool map[16][16]= {false};
bool flag=false;
int st;
int a[6]= {-1,1,0,0,0},b[6]= {0,0,-1,1,0};   
bool panduan()      
{
    for(int i=1; i<=4; i++)     
        for(int j=1; j<=4; j++)
        {
            if(map[i][j]!=map[1][1])
                return false;
        }
    return true;
}
void f(int r,int c)     
{
    for(int i=0; i<=4; i++)
        map[r+a[i]][c+b[i]]=!map[r+a[i]][c+b[i]];
    return;
}
void dfs(int r,int c, int deep)
{
    if(deep==st)       
    {
        flag=panduan();
        return;
    }
    if(flag||r==5) return;
    f(r,c);
    if(c<4)                  
        dfs(r,c+1,deep+1);
    else
        dfs(r+1,1,deep+1);
    f(r,c);              
    if(c<4)
        dfs(r,c+1,deep);
    else
        dfs(r+1,1,deep);
    return;
}
int main()
{
    char fi;
    for(int i=1; i<=4; i++)
        for(int j=1; j<=4; j++)
        {
            cin>>fi;
            if(fi=='b') map[i][j]=true;    
        }

    for(st=0; st<=16; st++)     
    {
        dfs(1,1,0);
        if(flag) break;
    }
    if(flag)
        cout<<st<<endl;
    else
        cout<<"Impossible"<<endl;
    return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_41654438/article/details/81448664