poj1753 - Flip Game

题目链接:点击打开链接


题目意思:

4*4棋盘,用b代表黑棋,用w表示白棋,棋盘由b或w组成,问能否经过最小次数ans次翻转,使得棋盘上全为黑棋,或者全为白棋。(翻转的规则为翻转某一棋子,周围4个棋子翻转)


思路:

dfs。对于每一个棋子,我们有两种选择,即翻棋子,和不翻棋子,很自然先翻棋子,回溯时不翻棋子。

有一个问题,如何保证步数是最少的?

有一个思路,我们枚举答案,看是否这个答案能够逆推回到初始状态。

进而,我们想从小到大的枚举答案,倘若在答案所表示的步数下,实现全黑或者全白,那么当前解就是最小解。


题目启示参考我的专题小结:点击打开链接


代码:

#include <iostream>
#include <cstring>
#include <cstdio>

using namespace std;

const int MAXN = 4;

int step;
bool flag=false;

bool board[MAXN+2][MAXN+2];

const int dx[5] = {0, 0, 0, 1, -1};
const int dy[5] = {0, -1, 1, 0, 0};

bool check(){
	for(int i=1; i<5; ++i)
		for(int j=1; j<5; ++j)
			if(board[i][j] != board[1][1])
				return false;
			return true;
}

void flip(int x, int y){
	for(int i=0; i<5; ++i){
		board[x+dx[i]][y+dy[i]] = !board[x+dx[i]][y+dy[i]];
	}
}


void dfs(int x, int y, int cnt){
	if(cnt==step){
		flag = check();
		return;
	}
	if(flag || x>=5) return;  //给其他运行的函数返回
	flip(x, y);
	if(y<4)
		dfs(x, y+1, cnt+1);
	else
		dfs(x+1, 1, cnt+1);
	flip(x, y);
	if(y<4)
		dfs(x, y+1, cnt);
	else
		dfs(x+1, 1, cnt);
}


int main(){
	char temp;
	for(int i=1; i<5; ++i){
		for(int j=1; j<5; ++j){
			//scanf("%c", &temp);
			cin>>temp;
			if(temp=='b') board[i][j] = true;
			else if(temp=='w') board[i][j] = false;
		}
	}
	for(step=0; step<16; ++step){
		dfs(1, 1, 0);
		if(flag) break; 
	}
	if(!flag)
		printf("Impossible\n");
	else
		printf("%d\n", step);
	return 0;
}




  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值