poj-2049 Finding Nemo *

【转】 (看了题目,感觉用广搜, 就没做~  直接转一个~ )



搜索题,我的做法是用优先队列(保证当前所通过的门是最少的),所以遇见出口,就可以直接得到结果,

搜索从Nemo的位置开始,有三种情况,遇见门,door加1,入队,遇见air,直接入队,遇见墙,
continue

我的存储结构见代码,

这里还要注意两点,一是Nemo的位置可能超出[
1--199],所以开始时有必要进行判断(因为这,n个runtime error ,郁闷了几个小时。。)二是这个如果用C++提交的话,好像输入Nemo的位置时,必须用cin(不能用scanf,当然G++也可以通过的),这是偶然在discuss上看到的,要不,不知又要郁闷多久。。。

#include
<stdio.h>
#include
<queue>
using namespace std;
int map[2][250][250],posi[250][250];//我用小方形的左下的坐标表示这个小方形(譬如,Nemo的坐标为(1.5,1.5),则他所在的小方形为(1,1)),posi[i][j]指的是小方形的坐标,map[0][i][j]为坐标为(i,j),平行于x轴的一个墙(或门,空气),map[1][i][j]则为平行于y轴的
typedef struct nn{
int x;
friend
bool operator<(struct nn n1,struct nn n2)
{
return n1.door > n2.door;
}
int y,door;
}po;
//door记录了到达小方形(i,j)所通过的最少门数,
int main(void)
{
int i,j,n,m,x,y,d,t,tx,ty,td,flag,door,txx,tyy,maxx,maxy,minx,miny;
int dd[4]={0,1,1,0},xx[4]={0,0,1,0},yy[4]={0,0,0,1},xxx[4]={0,-1,1,0},yyy[4]={-1,0,0,1};//dd[]指到某个方形后可去的四个方向,我是按下、左、右、上的顺序,xx[],yy[],xxx[],yyy[]与之对应,xx[],yy[]指去这个方向时要通过的边的坐标(map[][][]),xxx,yyy指通过边后到达的新的小方形的坐标(posi[][]),
double f1,f2;
po tem;
priority_queue
<po>q;
while(scanf("%d%d",&m,&n)!=EOF)
{
if(m==-1&&n==-1)
break;
for(i=0;i<201;i++)
for(j=0;j<=200;j++)
{
posi[i][j]
=0;
map[
0][i][j]=0;
map[
1][i][j]=0;//0指为air
}
maxx
=maxy=-20;
minx
=miny=220;
while(m--)
{
scanf(
"%d%d%d%d",&x,&y,&d,&t);
for(i=0;i<t;i++)
map[d][x
+i*(1-d)][y+i*d]=1;//1指墙
if(x<minx)
minx
=x;
if(y<miny)
miny
=y;
if(x>maxx)
maxx
=x;
if(y>maxy)
maxy
=y;
}
while(n--)
{
scanf(
"%d%d%d",&x,&y,&d);
map[d][x][y]
=2;//2指door
}
scanf(
"%lf%lf",&f1,&f2);
x
=(int)f1;
y
=(int)f2;
if(x<minx||y<miny||x>=maxx||y>=maxy)
{
printf(
"0\n");
continue;
}
while(!q.empty())
q.pop();
tem.x
=x;
tem.y
=y;
tem.door
=0;
q.push(tem);
flag
=0;
posi[x][y]
=1;
while(!q.empty())
{
tem
=q.top();
q.pop();
x
=tem.x;
y
=tem.y;
door
=tem.door;
if(x>=maxx||x<minx||y>=maxy||y<miny)
{
flag
=1;
break;
}
for(i=0;i<4;i++)
{
td
=dd[i];
tx
=xx[i]+x;
ty
=yy[i]+y;
txx
=xxx[i]+x;
tyy
=yyy[i]+y;
if(map[td][tx][ty]==2&&posi[txx][tyy]==0)
{
tem.x
=txx;
tem.y
=tyy;
tem.door
=door+1;
posi[txx][tyy]
=1;
q.push(tem);
}
if(map[td][tx][ty]==0&&posi[txx][tyy]==0)
{
posi[txx][tyy]
=1;
tem.x
=txx;
tem.y
=tyy;
tem.door
=door;
q.push(tem);
}
}
}
if(flag==1)
printf(
"%d\n",door);
else
printf(
"-1\n");
}
}

你可能感兴趣的:(find)