zoukankan      html  css  js  c++  java
  • 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;
    }
    
  • 相关阅读:
    C#中Dictionary的用法
    System.Timers.Timer用法
    C#中的异步调用及异步设计模式(三)——基于事件的异步模式
    C#中的异步调用及异步设计模式(二)——基于 IAsyncResult 的异步设计模式
    C#中的异步调用及异步设计模式(一)
    [你必须知道的异步编程]——异步编程模型(APM)
    strncasecmp与strcasecmp用法
    C语言之strrchr函数
    HDU 5289 Assignment (ST算法区间最值+二分)
    poj 1733 Parity game(种类并查集)
  • 原文地址:https://www.cnblogs.com/nanke/p/2272042.html
Copyright © 2011-2022 走看看