poj 1753 Flip Game——dfs深搜

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:
Choose any one of the 16 pieces.
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).

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

题意: 有一个4*4的棋盘,给定棋盘上的棋子的摆放的正反面(棋子分黑白两面,黑的背面是白,白的背面是黑)。规定游戏规则如下:

  • 选择一枚棋子进行反转,这枚棋子周边的其他四枚棋子也跟着反转(该棋子的上下左右四枚棋子),即原来是是白就反转成黑色,原来为黑反转为白。
  • 操作一次记录一次操作步数。

求:
  最小的反转次数能使得所有棋子变成同色,同黑或者同白,如果无论怎么操作都无法使得棋子同色,那么输出不带引号的“Impossible”,否则输出最小操作步数。

题解:

  • 首先。要想到我们最多执行的步数只会是16步。(可以假设一下我们从坐标(0,0)的棋子开始翻一直翻到(3,3))因为在第十六步的时候我们已经把棋盘上面所有的棋子都翻了一个遍,这时候第十七次翻转的时候我们又回到的(0,0)棋子的翻转。仔细想想,这时候再翻一次(0,0)就又还原到初始那一面了。所有,最多只会翻转16次,当超过16次棋子的颜色还没有同色的话即说明不论怎么操作都无法使得所有棋子翻转到相同的颜色。
  • 我们接下来枚举每一个棋子,当达到同色时退出循环。每个棋子有两个选择,翻或不翻。

c++ AC 代码

#include<iostream>
#include<cstdio>
#define INF 0x3f3f3f3f
char daze[5][5];    // 这里数组要开到5 用scanf读入的时候会把那个回车也读进去
int num;
int pos[5][2] = {0,0,0,1,0,-1,1,0,-1,0};	// 当前棋子以及它周边四个方向的棋子坐标

bool check()	// 判断是否所有棋子同色
{
	char ch = daze[0][0];
	for(int i=0;i<4;i++)
		for(int j=0;j<4;j++)
			if(daze[i][j]!=ch)
				return 0;
	return 1;
}

void swap_chess(int x,int y)    // 翻转函数
{
	for(int i=0;i<5;i++)
	{
		int xi = x+pos[i][0],yi = y+pos[i][1];
		if(xi<4 && xi>=0 && yi<4 && yi>=0)
		{
			if(daze[xi][yi] == 'w')
				daze[xi][yi] = 'b';
			else
				daze[xi][yi] = 'w';
		}
	}
}

void dfs(int x,int y,int step)		// x代表行坐标,y代表列坐标,step代表已经走过的步数
{
	if(step>16)	return;			// 步数大于16的时候退出
	if(check())
	{
		if(step<num)			// 维护最小值
			num = step;
		return;
	}
	if(y==4)					// 按行搜索,搜完一行换到下一行
	{
		x++;
		y=0;
	}
	if(x==4)	return;			// 搜完了,返回
	for(int i=0;i<2;i++)
	{
		if(i==0)		// 翻
		{
			swap_chess(x,y);		// 将该位置的棋子翻转
			dfs(x,y+1,step+1);		// 翻转后步数+1 进入下一层递归
			swap_chess(x,y);		// 回溯 将翻转过的棋子复原
		}
		else		// 不翻
			dfs(x,y+1,step);    // 不翻则没有必要将步数+1
	}
}

int main()
{
	num = INF;
	for(int i=0;i<4;i++)
		scanf("%s",daze[i]);
	dfs(0,0,0);
	if(num<=16)
		printf("%d\n",num);
	else
		puts("Impossible");
	return 0;
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值