POJ 1753 Flip Game BFS/DFS

 题意:给定一个4*4的棋盘。棋盘上每个格子有黑白两种状态。每修改一个格子的状态,那么它上下左右的格子也随之被修改。目标是让所有格子都变成黑或者所有格子都变成白。问至少需要修改几次才能实现目标。
题解:给出了DFS,BFS两种解法。
DFS:

#include <iostream>
using namespace std;

int MIN; 
bool cell[16];

bool success()
{
	for ( int i = 0; i < 16; i++ )
		if ( cell[i] != cell[0] )
			return false;
		return true;
}

void flip ( int n )
{
	if ( n % 4 != 0 )
		cell [n-1] = !cell[n-1];
	if ( n % 4 != 3 )
		cell [n+1] = !cell[n+1];
	if ( n <= 11 )
		cell [n+4] = !cell[n+4];
	if ( n >= 4 )
		cell [n-4] = !cell[n-4];
	cell[n] = !cell[n];
}


void dfs ( int Nth_cell, int step )
{
	bool check = success ();
	if ( check || Nth_cell >= 16 )
	{
		if ( check && step < MIN )
			MIN = step;
		return;
	}
	flip ( Nth_cell );
	dfs ( Nth_cell + 1, step + 1 );
    flip ( Nth_cell );
	dfs ( Nth_cell + 1, step );
}


int main()
{
	char ch;
	memset(cell,0,sizeof(cell));
	for ( int i = 0; i < 16; i++ )
	{
		cin >> ch;
		if ( ch == 'b' )
			cell[i] = 1;
	}
	MIN = 17; // 最小步骤只要先设定大于16步即可。因为最多值需翻16次(每个格子翻一次,翻了两次等于没翻,翻了三次等于一次···)
	dfs ( 0, 0 );
	if ( MIN == 17 )
		cout << "Impossible" << endl;
	else
		cout << MIN << endl;
	return 0;
}

BFS:
#include <queue>
#include <iostream>
using namespace std;

#define Black 65535
#define White 0
int state [65536];


int filp ( int state_id, int position )
{
	state_id ^= ( 1 << position );
	if ( position >= 4 )
		state_id ^= ( 1 << ( position-4 ) );
	if ( position <= 11 )
		state_id ^= ( 1 << ( position+4 ) );
	if ( position % 4 > 0 )
		state_id ^= ( 1 << ( position-1 ) );
	if ( position % 4 < 3 )
		state_id ^= ( 1 << ( position+1 ) );
	return state_id;
}


int main()
{
	char ch;
	int current = 0;
	queue<int> search;
	memset( state, -1, sizeof(state) );
	for ( int i = 0; i < 16; i++ )
	{
		cin >> ch;
		if ( ch == 'b' )
			current += ( 1 << i );
	}
	if ( current == Black || current == White )
	{
		cout << 0 << endl;
		return 0;
	}
	state[current] = 0;
	search.push ( current );
	int next;
	while ( ! search.empty () )
	{
		current = search.front ();
		search.pop ();
		for ( int i = 0; i < 16; i++ )
		{
			next = filp ( current, i );
			if ( next == Black || next == White )
			{
				cout << state[current] + 1 << endl;
				return 0;
			}
			if ( state[next] == -1 )
			{
				search.push ( next );
				state[next] = state[current]+1;
			}
		}
	}
	cout << "Impossible" << endl;
	return 0;
}


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值