您的位置:首页 > 其它

poj 1753 Flip Game(位运算+bfs)

2014-04-20 12:53 417 查看
http://poj.org/problem?id=1753

题意:给一个只含‘b’和‘w’的4*4的棋盘,当翻一个格子时,它上下左右的格子也要翻转,问最少需要多少步使棋盘全是‘b’或‘w’。

因为棋盘4*4,共16个格子,每个格子用二进制0,1表示黑和白,整个棋盘共65535中状态。用x表示初始状态,然后枚举翻转每个格子,进行bfs。当状态为0或65535时表示说明全是‘b’或‘w’.

#include <stdio.h>
#include <string.h>
#include <algorithm>
#include <stack>
#include <vector>
#include <queue>
#define LL long long
#define _LL __int64
using namespace std;

struct node
{
	int sta;
	int step;
};
char map[4][4];
queue <node> que;
int vis[65536];

//当前状态是cur,计算当翻转第i个格子后的状态
int filp(int cur, int i)
{
	cur = cur ^ (1<<i);
	if(i > 3)
		cur = cur ^ (1<<(i-4));
	if(i < 12)
		cur = cur ^ (1<<(i+4));
	if(i%4 != 0)
		cur = cur ^ (1<<(i-1));
	if(i%4 != 3)
		cur = cur ^ (1<<(i+1));
	return cur;
}

void bfs(int x)
{
	memset(vis,0,sizeof(vis));
	while(!que.empty()) que.pop();

	vis[x] = 1;
	que.push((struct node){x,0});

	while(!que.empty())
	{
		struct node u = que.front();
		que.pop();

		if(u.sta == 0 || u.sta == 65535)
		{
			printf("%d\n",u.step);
			return;
		}

		for(int i = 0; i < 16; i++)
		{
			int tmp = filp(u.sta,i);
			if(!vis[tmp])
			{
				vis[tmp] = 1;
				que.push((struct node){tmp,u.step+1});
			}
		}
	}
	printf("Impossible\n");
}

int main()
{
	int x;
	x = 0;
	for(int i = 0; i < 4; i++)
	{
		scanf("%s",map[i]);
		for(int j = 0; j < 4; j++)
		{
			if(map[i][j] == 'w')
				x <<= 1;
			else
				x = (x << 1) + 1;
		}
	}

	bfs(x);
	return 0;

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: