zoukankan      html  css  js  c++  java
  • hdu3278 Puzzle (BFS)

    题意: 给一个4X6的矩形,有white ,blank , grey 三种颜色各有8个格子 ,给定一个初始状态,求用最少的操作次数将图形变化为中间的8个格子颜色相同。

    分析:话说,因为做过了hdu1667,一开始真的以为IDA*稳过的,敲完之后,直接TLE了,实在不解啊,原来是有测试数据的量太大了。

    按照大牛的思路是这样的:当我们确定了要将中间转成什么颜色之后,转的时候发现,另外俩种颜色也就没必要区分了,所以也就可以看成是只有俩种颜色了,之后用24个位保存状态,用BFS预处理从最终状态到每一个状态需要的最小步数。最后再根据所给的图,判断将哪种颜色转到中间的步数最少即可。

    虽然知道是这样的思路之后,还是一直TLE了,原来下面这俩种状态转换模式速度差那么多,ORZ

    inline unsigned int changetostate()
    {
    	unsigned int t=0;
    	for(int i=0;i<4;i++)
    		for(int j=0;j<6;j++)
    		{
    			t<<=1;
    			t+=(map[i][j]-'0');
    		}
    	return t;
    }
    inline void changetomap(unsigned int t)
    {
    	for(int i=3;i>=0;i--)
    		for(int j=5;j>=0;j--)
    		{
    			map[i][j]= (t&1)+'0';
    			t>>=1;
    		}
    }
    

     下面这种比较慢,改成那么那种就过了,1200+ms

    inline unsigned int changetostate()
    {
        unsigned int t=0;
        int i,j;
        for(int k=0;k<24;k++)
        {
            i=k/6;j=k%6;
            if(map[i][j]=='1')
                t|=(1<<k);
        }
        return t;
    }
    inline void changetomap(unsigned int t)
    {
        int i,j;
        for(int k=0;k<24;k++)
        {
            i=k/6;j=k%6;
            if(t&(1<<k))
                map[i][j]='1';
            else map[i][j]='0';
        }
    }
    

     看整个代码吧:

    #include<iostream>
    #include<algorithm>
    #include<queue>
    using namespace std;
    char step[1<<24];
    char map[5][7];
    char hash1[3]={'B','G','W'};
    void init()
    {
    	for(int i=0;i<4;i++)
    		for(int j=0;j<6;j++)
    			map[i][j]='0';
    	for(int i=1;i<3;i++)
    		for(int j=1;j<5;j++)
    			map[i][j]='1';
    	memset(step,-1,sizeof(step));
    }
    inline unsigned int changetostate()
    {
    	unsigned int t=0;
    	for(int i=0;i<4;i++)
    		for(int j=0;j<6;j++)
    		{
    			t<<=1;
    			t+=(map[i][j]-'0');
    		}
    	return t;
    }
    inline void changetomap(unsigned int t)
    {
    	for(int i=3;i>=0;i--)
    		for(int j=5;j>=0;j--)
    		{
    			map[i][j]= (t&1)+'0';
    			t>>=1;
    		}
    }
    inline void TurnL(int x)
    {
    	char c=map[x][0];
    	for(int i=0;i<5;i++)
    		map[x][i]=map[x][i+1];
    	map[x][5]=c;
    }
    inline void TurnR(int x)
    {
    	char c=map[x][5];
    	for(int i=5;i>=1;i--)
    		map[x][i]=map[x][i-1];
    	map[x][0]=c;
    }
    inline void TurnU(int x)
    {
    	char c=map[0][x];
    	for(int i=0;i<3;i++)
    		map[i][x]=map[i+1][x];
    	map[3][x]=c;
    }
    inline void TurnD(int x)
    {
    	char c=map[3][x];
    	for(int i=3;i>=1;i--)
    		map[i][x]=map[i-1][x];
    	map[0][x]=c;
    }
    void BFS(unsigned int f)
    {
    	queue<unsigned int> Q;
    	Q.push(f);
    	step[f]=0;
    	unsigned int temp;
    	unsigned int t=0;
    	while(!Q.empty())
    	{
    		temp=Q.front();
    		Q.pop();
    		changetomap(temp);
    		for(int i=0;i<6;i++)
    		{
    			TurnU(i);
    			t=changetostate();
    			if(step[t]==-1)
    			{
    				Q.push(t);
    				step[t]=step[temp]+1;
    			}
    			TurnD(i);
    			TurnD(i);
    			t=changetostate();
    			if(step[t]==-1)
    			{
    				Q.push(t);
    				step[t]=step[temp]+1;
    			}
    			TurnU(i);
    		}
    		for(int i=0;i<4;i++)
    		{
    			TurnR(i);
    			t=changetostate();
    			if(step[t]==-1)
    			{
    				Q.push(t);
    				step[t]=step[temp]+1;
    			}
    			TurnL(i);
    			TurnL(i);
    			t=changetostate();
    			if(step[t]==-1)
    			{
    				Q.push(t);
    				step[t]=step[temp]+1;
    			}
    			TurnR(i);
    		}
    	}
    }
    int main()
    {
    	int cas=0,T;
    	init();
    	BFS(changetostate());
    	scanf("%d",&T);
    	while(T--)
    	{
    		for(int i=0;i<4;i++)
    			scanf("%s",map[i]);
    		printf("Case %d: ",++cas);
    		int ans=INT_MAX;
    		unsigned int t;
    		for(int i=0;i<3;i++)
    		{
    			t=0;
    			for(int j=0;j<4;j++)
    				for(int k=0;k<6;k++)
    				{
    					t<<=1;
    					if(map[j][k]==hash1[i])
    						t+=1;
    				}
    			if(ans>step[t])
    				ans=step[t];
    		}
    		printf("%d\n",ans);
    	}
    	return 0;
    }
    
  • 相关阅读:
    ‘Found duplicate PV’ warnings when using LVM with multipath storage in RHEL/CentOS
    如何卸载windows的服务?卸载服务
    富文本wangeditor层级太高覆盖问题
    vue wangeditor
    vue消息提示this.$message方法
    MySQL之查询指定时间的数据
    企业微信第三方应用PC端实现用户点击注册的三种方式
    两款不带广告的輸入法
    jquery、css 的选择器
    广信可视电话设置可安装应用权限
  • 原文地址:https://www.cnblogs.com/nanke/p/2283306.html
Copyright © 2011-2022 走看看