pku 1753 (BFS)

额,

题意:

 

给定一个4*4的黑白棋盘的初始状态,判断能否通过满足一些给定的翻转规则,使得所有棋面的颜色都一样,如果可以,输出最小步数;
分析:
我一点优化都没有,直接BFS暴搜,中间有一个state整型变量保存整个图的当前信息,因为总共就16个位,所以刚刚,取出一个状态的 时候,再将state转换为图,可能直接在每一个状态里面保存图回更快些吧,内存应该也不太
#include<iostream>
#include<algorithm>
#include<queue>
using namespace std;
struct node
{
	int cnt;
	int state;
	node(int a=0,int b=0):cnt(a),state(b){}
};
bool vis[1<<16];
int g[4][4];
char map[4][4];
int ans,num=0;
queue<node> Q;
void changetograph(int state)
{
	for(int i=0;i<4*4;i++)
	{
		if(state&(1<<i))
			g[i/4][i%4]=1;
		else g[i/4][i%4]=0;
	}
}
int changetostate(int x,int y)
{
	int temp=0;
	int t[4][4];
	for(int i=0;i<4;i++)
		for(int j=0;j<4;j++)
			t[i][j]=g[i][j];
	t[x][y]^=1;//悲剧性的少了这一句,找了很久orz
	if(x-1>=0) t[x-1][y]^=1;
	if(y-1>=0) t[x][y-1]^=1;
	if(x+1<4)  t[x+1][y]^=1;
	if(y+1<4)  t[x][y+1]^=1;
	for(int i=0;i<4;i++)
		for(int j=0;j<4;j++)
			if(t[i][j]==1)
				temp|=(1<<(4*i+j));
	return temp;
}
bool BFS()
{
	node temp;
	while(!Q.empty())
	{
		temp=Q.front();
		Q.pop();
		changetograph(temp.state);
		/*for(int i=0;i<4;i++)
		{
			for(int j=0;j<4;j++)
				printf("%d ",g[i][j]);
			printf("\n");
		}*/
		if(temp.state==0 || temp.state==((1<<16)-1))
		{
			ans=temp.cnt;
			return true;
		}
		
		for(int i=0;i<4;i++)
		{
			for(int j=0;j<4;j++)
			{
				int t=changetostate(i,j);
				if(!vis[t])
				{
					Q.push(node(temp.cnt+1,t));
					vis[t]=true;
				}
			}
		}
	}
	return false;
}
int main()
{
	int st=0;
	for(int i=0;i<4;i++)
	{
		scanf("%s",map[i]);
		for(int j=0;j<4;j++)
		{
			if(map[i][j]=='b')
			{
				st|=(1<<(4*i+j));
				g[i][j]=1;
			}
			else g[i][j]=0;
		}
	}

	//for(int i=0;i<4;i++)
	//{
	//	for(int j=0;j<4;j++)
	//		printf("%d ",g[i][j]);
	//	printf("\n");
	//}
	memset(vis,false,sizeof(vis));
	vis[st]=true;
	Q.push(node(0,st));
	if(BFS())
		printf("%d\n",ans);
	else printf("Impossible\n");
	return 0;
}

 

posted @ 2011-12-02 14:09  枕边梦  阅读(221)  评论(0编辑  收藏  举报