POJ_2049_Finding Nemo(BFS+优先队列)

/*
看了网络大神的代码,觉得要学习的东西真的很多,下面把我看完代码之后的理解分享一下。
这道题用到的算法就是广度优先遍历(BFS)和优先队列。别人不说是广搜,真的看不出来。
1:题意就是一个人从外面往方格里面走只能经过门,不能经过墙。
问你到达目的点最少经过的门数。可以反向思维我们可以从里面往外走,找最少的门数。
2:优先队列的用法,见代码,在这里优先队列的作用就是,每次出队的时候不是先入得先出
而是找门数最少的先出队。
3:广度搜索。while循环那里就是使用了广搜,因为广搜的实现就是用的队列。
4:上下左右方向移动的实现,用的师叔祖实现,而不是if控制。
*/

  1 # include <stdio.h>
  2 # include <string.h>
  3 # include <queue>
  4 using namespace std;
  5 int map[250][250][2],position[250][250];
  6 //我用小方形的左下的坐标表示这个小方形(譬如,Nemo的坐标为(1.5,1.5)
  7 //则他所在的小方形为(1,1)posi[i][j]指的是小方形的坐标,
  8 //map[0][i][j]为坐标为(i,j),平行于x轴的一个墙(或门,空气),map[1][i][j]则为平行于y轴的...
  9 typedef struct node
 10 {
 11     int x;
 12     friend bool operator < (struct node a,struct node b)
 13     {
 14         return a.door>b.door;
 15     }
 16     int y,door;
 17 }LINK;
 18 int main()
 19 {
 20     int i,j,n,m,x,y,d,t;
 21     int tx,ty,td,flag,door,txx,tyy;
 22     int maxx,maxy,minx,miny;
 23     int dd[4]={0,1,1,0},xx[4]={0,0,1,0},yy[4]={0,0,0,1};
 24     int xxx[4]={0,-1,1,0},yyy[4]={-1,0,0,1};
 25 //        dd[]指到某个小正方形里面后可去的四个方向,我是按下、左、右、上的顺序,
 26 //        xx[],yy[],xxx[],yyy[]与之对应,xx[],yy[]指去这个方向时
 27 //        要通过的边的坐标(map[][][]),
 28 //        xxx,yyy指通过边后到达的新的小方形的坐标(posi[][]),
 29     double f1,f2;
 30     LINK tem;
 31     priority_queue<LINK> q;
 32     while(scanf("%d%d",&m,&n)!=EOF)
 33     {
 34         if(m==-1 && n==-1)
 35             break;
 36         memset(map,0,sizeof(map));
 37         memset(position,0,sizeof(position));
 38         maxx=maxy=-20;
 39         minx=miny=220;
 40         while(m--)
 41         {
 42             scanf("%d%d%d%d",&x,&y,&d,&t);
 43             for(i=0;i<t;i++)
 44                 map[x+i*(1-d)][y+i*d][d]=1;//1指墙
 45             if(x<minx)
 46                 minx=x;
 47             if(y<miny)
 48                 miny=y;
 49             if(x>maxx)
 50                 maxx=x;
 51             if(y>maxy)
 52                 maxy=y;
 53         }
 54         while(n--)
 55         {
 56             scanf("%d%d%d",&x,&y,&d);
 57             map[x][y][d]=2;//2指门
 58         }
 59         scanf("%lf%lf",&f1,&f2);
 60         x=(int) f1;
 61         y=(int) f2;
 62         if(x<minx || y<miny ||x>maxx || y>maxy)
 63         {
 64             printf("0\n");
 65             continue;
 66         }
 67         while(!q.empty())
 68             q.pop();
 69         tem.x=x;
 70         tem.y=y;
 71         tem.door=0;
 72         q.push(tem);
 73         flag=0;
 74         position[x][y]=1;
 75         while(!q.empty())
 76         {
 77             tem=q.top();
 78             q.pop();
 79             x=tem.x;
 80             y=tem.y;
 81             door=tem.door;
 82             if(x>=maxx || x<minx || y>=maxy || y<miny)
 83             {
 84                 flag=1;break;
 85             }
 86             for(i=0;i<4;i++)
 87             {
 88                 td=dd[i];
 89                 tx=xx[i]+x;
 90                 ty=yy[i]+y;
 91                 txx=xxx[i]+x;
 92                 tyy=yyy[i]+y;
 93                 if(map[tx][ty][td]==2 && position[txx][tyy]==0)
 94                 {
 95                     tem.x=txx;
 96                     tem.y=tyy;
 97                     tem.door=door+1;
 98                     position[txx][tyy]=1;
 99                     q.push(tem);
100                 }
101                 if(map[tx][ty][td]==0 && position[txx][tyy]==0)  
102                 {    
103                     position[txx][tyy]=1;   
104                     tem.x=txx;  
105                     tem.y=tyy;   
106                     tem.door=door;  
107                     q.push(tem); 
108                 }
109             }
110         }
111         if(flag==1)
112             printf("%d\n",door);
113         else
114             printf("-1\n");
115     }
116     return 0;
117 }

 

posted on 2013-08-13 16:20  随风浪子的博客  阅读(555)  评论(0编辑  收藏  举报

导航