现在的位置: 首页 > 综合 > 正文

hdu3278 Puzzle (BFS)

2012年11月21日 ⁄ 综合 ⁄ 共 2557字 ⁄ 字号 评论关闭

题意: 给一个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;
}

 

抱歉!评论已关闭.