Holedox Moving--POJ 1324

1、题目类型:模拟、贪吃蛇游戏、哈希表、BFS。

2、解题思路:题意,给出活动空间大小、蛇身位置、空间中障碍物位置、目标位置,求解蛇的最少移动步数。难点,用进制的哈希对蛇身相对位置的保存。步骤,(1)根据输入记录Holedox的位置和stones的位置;(2)对Holedox的位置进行哈希状态压缩,哈希加密方式为Staten=Holedox位置的逐一相对位置的4进制*总行数*总列数+总行数*行位置+列位置(解密方式类似);(3)BFS搜索目标情况,成功解密Holedox‘s head位置为(0,0)返回此时step,否则返回-1。

3、注意事项:哈希的构造方法必须唯一,且在int的控制范围以内否则TLE;BFS中常用变量尽量用全局变量,避免Runtime Error。

4、实现方法:

#pragma warning(disable:4786)
#include
<iostream>
#include
<queue>
#include
<map>
using namespace std;

struct Node
{
int state;
int step;
};

Node Q[
1000000];
int X[4]={0,1,0,-1};
int Y[4]={1,0,-1,0};
int R,C,L,state;
int sn[9][2],mat[30][30];
bool vis[6800000];
map
<int,int> S;

void Init()
{
int i,n,a,b;
for(i=0;i<L;i++)
{
scanf(
"%d%d",&sn[i][0],&sn[i][1]);
sn[i][
0]--;
sn[i][
1]--;
}
cin
>>n;
memset(mat,
0,sizeof(mat));
for(i=0;i<n;i++)
{
scanf(
"%d%d",&a,&b);
a
--;
b
--;
mat[a][b]
=1;
}
S.clear();
}

//获得Holedox相对位置
int GetDir(int now[2],int pre[2])
{
if(now[1]==pre[1]+1)
return 0;
if(now[1]==pre[1]-1)
return 2;
if(now[0]==pre[0]+1)
return 1;
if(now[0]==pre[0]-1)
return 3;
return 0;
}

bool Judge(int ssn[][2],int sn[][2])
{
int i;
if(!(ssn[0][0]>=0&&ssn[0][0]<R&&ssn[0][1]>=0&&ssn[0][1]<C&&mat[ssn[0][0]][ssn[0][1]]==0))
return false;
for(i=0;i<L;i++)
{
if(ssn[0][0]==sn[i][0]&&ssn[0][1]==sn[i][1])
return false;
}
return true;
}

int BFS()
{
int i,j,k,front=0,rear=0;
int head[2],tsn[9][2];
Node tmp;
memset(vis,
0,sizeof(vis));
tmp.state
=state;
tmp.step
=0;
Q[rear
++]=tmp;
vis[state]
=1;
while(front<rear)
{
tmp
=Q[front];
front
=(front+1)%1000000;
head[
1]=tmp.state%(C*R)%C;
head[
0]=tmp.state%(C*R)/C;
state
=tmp.state/(C*R);
sn[
0][0]=head[0];
sn[
0][1]=head[1];
for(i=1;i<L;i++)
{
sn[i][
0]=sn[i-1][0]+X[state%4];
sn[i][
1]=sn[i-1][1]+Y[state%4];
state
/=4;
}
if(head[0]==0&&head[1]==0)
return tmp.step;
for(i=0;i<4;i++)
{
tsn[
0][0]=sn[0][0]+X[i];
tsn[
0][1]=sn[0][1]+Y[i];
if(Judge(tsn,sn))
{
state
=0;
int s=1;
for(j=1;j<L;j++)
{
tsn[j][
0]=sn[j-1][0];
tsn[j][
1]=sn[j-1][1];
}
for(k=1;k<L;k++)
{
state
=state+GetDir(tsn[k],tsn[k-1])*s;
s
*=4;
}
state
=state*R*C+tsn[0][0]*C+tsn[0][1];
if(!vis[state])
{
Node N;
N.state
=state;
N.step
=tmp.step+1;
vis[state]
=1;
Q[rear]
=N;
rear
=(rear+1)%1000000;
}
}
}
}
return -1;
}

void Solve(int ca)
{
int i,s=1;
state
=0;
for(i=1;i<L;i++)
{
state
=state+GetDir(sn[i],sn[i-1])*s;
s
*=4;
}
state
=state*R*C+sn[0][0]*C+sn[0][1];
cout
<<"Case "<<ca++<<": ";
cout
<<BFS()<<endl;
}

int main()
{
int ca=1;
while(scanf("%d%d%d",&R,&C,&L))
{
if(R==0&&C==0&&L==0)
break;
Init();
Solve(ca
++);
}
return 0;
}

 

posted @ 2010-10-05 11:29  勇泽  阅读(1996)  评论(0编辑  收藏  举报