poj 1753 Flip Game (枚举+搜索)

Description

Flip game is played on a rectangular 4x4 field with two-sided pieces placed on each of its 16 squares. One side of each piece is white and the other one is black and each piece is lying either it's black or white side up. Each round you flip 3 to 5 pieces, thus changing the color of their upper side from black to white and vice versa. The pieces to be flipped are chosen every round according to the following rules:
  1. Choose any one of the 16 pieces.
  2. Flip the chosen piece and also all adjacent pieces to the left, to the right, to the top, and to the bottom of the chosen piece (if there are any).

poj 1753 Flip Game (枚举+搜索)_第1张图片Consider the following position as an example:

bwbw
wwww
bbwb
bwwb
Here "b" denotes pieces lying their black side up and "w" denotes pieces lying their white side up. If we choose to flip the 1st piece from the 3rd row (this choice is shown at the picture), then the field will become:

bwbw
bwww
wwwb
wwwb
The goal of the game is to flip either all pieces white side up or all pieces black side up. You are to write a program that will search for the minimum number of rounds needed to achieve this goal.

Input

The input consists of 4 lines with 4 characters "w" or "b" each that denote game field position.

Output

Write to the output file a single integer number - the minimum number of rounds needed to achieve the goal of the game from the given position. If the goal is initially achieved, then write 0. If it's impossible to achieve the goal, then write the word "Impossible" (without quotes).

Sample Input

bwwb
bbwb
bwwb
bwww

Sample Output

4
题意:
在一个4X4的矩形方格上玩翻转游戏,每个方格有一个棋子,每个棋子有两个面,一个面是白色,一个面是黑色。每一轮你都可以翻3-5个棋子。规则是,随意选一个在位置[i,j]的棋子来翻转,并且连同它上下左右的4个棋子一块翻转。b代表黑色,w代表白色。这个题的目标是要么都变成黑色,要么都变成白色,问最少要多少轮达成这两个目标之一。
输入初始图,如果这个图已经正确了就输出0,如果不能达成目标就输出Impossible,否则就输出最小轮数。
这个题就是用枚举举遍所有情况,然后一个一个深搜看看是不是符合条件,符合条件直接退出,不符合则继续,由于表格只有16个,所以可以得知最多的步数只能是16,所以可以根据步数从0到16依次枚举,第一个符合条件的就是最小的步数。
 
参考了别人的代码
#include <iostream>
#include <string.h>
using namespace std;
int pieces[4][4],ans;
bool flag;
int dir[5][2]={0,-1,0,1,-1,0,1,0,0,0}; //用来翻棋的坐标变化
bool check()      //用来检查这个图是不是已经到了目标的要求
{
    for(int i=0;i<4;i++)
      for(int j=0;j<4;j++)
        if(pieces[i][j]!=pieces[0][0])
          return false;
    return true;  //是的话返回真  
}
void convert(int row,int col)  //用来翻转棋子
{
    for(int i=0;i<5;i++)
    {
        int sx=row+dir[i][0],sy=col+dir[i][1];
        if(sx<0||sx>3||sy<0||sy>3)
            continue;
        pieces[sx][sy]=!pieces[sx][sy];
    }
    return;
}
void DFS(int row,int col,int step) //一行一行的搜索
{
    if(ans==step)
    {
        flag=check();
        return;
    }
    convert(row,col);   //翻棋子
    if(flag||row==4)
        return;
    if(col<3)
        DFS(row,col+1,step+1);
    else
        DFS(row+1,0,step+1);
    convert(row,col);  //不行的话就翻回来
    if(col<3)
        DFS(row,col+1,step);
    else
        DFS(row+1,0,step);
    return;
}
int main()
{
    int i,j;
    char temp;
    memset(pieces,0,sizeof(pieces)); //初始化为0
    for(i=0;i<4;i++)
       for(j=0;j<4;j++)
        {
            cin>>temp;
            if(temp=='b')
              pieces[i][j]=1; //定义pieces数组存储初始图,1代表b,0代表w
        }
    for(ans=0;ans<=16;ans++)  //对每一步产生的可能进行枚举
    {
        DFS(0,0,0);  //每一次都从(0,0)开始搜索
        if(flag)
            break;
    }
    if(flag)
        cout<<ans<<endl;
    else
        cout<<"Impossible"<<endl;
    return 0;
}
 

你可能感兴趣的:(poj 1753 Flip Game (枚举+搜索))