Uva 11047 The Monocycle 优先队列BFS

来源:互联网 发布:校园网络系统集成方案 编辑:程序博客网 时间:2024/05/22 01:50

A monocycle is a cycle that runs on one wheel and the one we will be considering is a bit more special. 
It has a solid wheel colored with five different colors as shown in the figure: 


                                                       
    The colored segments make equal angles (72deg  ) at the center.A monocyclist rides this cycle on an M  × N  grid of  square tiles.   The tiles  have such size  that moving forward from the center of one tile to that of the next one makes the wheel rotate exactly 72deg around its own center.  The effect is shown in the above figure.    When the wheel is at the center of square 1, the midpoint of the periphery of its 
blue segment is in touch with the ground.  But when the wheel moves forward to the center of the next square (square 2) the midpoint of its white segment touches the ground. 


    Some of the squares of the grid are blocked and hence the cyclist cannot move to them.  The cyclist 
starts from some square and tries to move to a target square in minimum amount of time.                From any 
square either he moves forward to the next square or he remains in the same square but turns 90deg left or  right. Each  of  these  actions  requires  exactly  1  second  to  execute. He  always  starts  his  ride  facing 
north  and  with  the  midpoint  of  the  green  segment  of  his  wheel  touching  the  ground.   In  the  target square, too, the green segment must be touching the ground but he does not care about the direction 
he will be facing. 
    Before he starts his ride, please help him find out whether the destination is reachable and if so the 
minimum amount of time he will require to reach it. 


Input 


The input may contain multiple test cases. 
    The  first  line  of  each  test  case  contains  two  integers M  and  N   (1  ≤  M ,  N   ≤  25)  giving  the 
dimensions of the grid.  Then follows the description of the grid in  M  lines of N  characters each.  The 
character  ‘#’  will  indicate  a  blocked  square,  all  other  squares  are  free. The  starting  location  of  the 
cyclist is marked by ‘S’ and the target is marked by ‘T’. 
    The input terminates with two zeros for M  and N . 


Output 


For  each  test  case  in  the  input  first  print  the  test  case  number  on  a  separate  line  as  shown  in  the 
sample output.  If the target location can be reached by the cyclist print the minimum amount of time 
(in  seconds)  required  to  reach  it  exactly  in  the  format  shown  in  the  sample  output,  otherwise,  print 
“destination     not   reachable”. 
    Print a blank line between two successive test cases. 


Sample Input 


1  3 
S#T 
10  10 
#S.......# 
#..#.##.## 
#.##.##.## 
 .#....##.# 
##.##..#.# 
#..#.##... 
#......##. 
 ..##.##... 
#.###...#. 
#.....###T 
0  0 


Sample Output 


Case   #1 
destination     not   reachable 


Case   #2 
minimum    time  =  49  sec 


再一次强烈提醒自己:Uva上的题目不能多回车,否则WA!Uva上的题目不能多回车,否则WA!Uva上的题目不能多回车,否则WA!重要的事情说三遍!!!


一道简单的BFS题目竟然卡在了回车上,简直醉生梦死。。。

题意:从起点到终点,向前走一步或者原地转向90°都需要花费1s时间,问最短时间

思路:用visit数组记录状态,进行BFS。我不知道大家对于visit数组是怎样理解的,实际上,我更愿意把它理解为state数组,因为在地图上走到一个位置,总会可以通过一些特征标记出一些状态。

对于这道题目,我们很明显可以看出,在地图上一个位置需要由r(行),c(列),dir(方向),cor(颜色)四个状态值决定,因此,visit数组是四维的,即使在相同的位置,也可能是不同的状态。

到达终点不仅需要在位置上到达,还需要满足题目中的颜色需求,这个很容易解决,因为每走一个格子变一种颜色,所以只要让走过的格子数量对5取余,看是否等于0即可。

另外,为了找出花费时间最少的路径,我们需要使用优先队列,这样,找到的第一个答案就是最短时间,注意自定义结构体对于优先级重载的方法。


Code:

#include <iostream>#include <stdio.h>#include <queue>#include <string.h>#include <math.h>#define MAX 30using namespace std;struct P{    int r,c,Time,dir,cor;    P(int r_,int c_,int t_,int d_,int cor_):r(r_),c(c_),Time(t_),dir(d_),cor(cor_) {}    bool operator < (const P &a) const    {        return Time>a.Time;    }};int n,m;char Map[MAX][MAX];bool vis[MAX][MAX][4][5];int dr[]= {-1,0,1,0}; //N,E,S,Wint dc[]= {0,1,0,-1};priority_queue<P> p;void init(){    while(!p.empty())        p.pop();    memset(vis,false,sizeof(vis));}bool judge(int nr,int nc){    return (nr>=0&&nr<m&&nc>=0&&nc<n);}int get_step( int nd, int d){    if((int)fabs(nd-d)==2)        return 2;    else        return 1 ;}int bfs(){    int nr,nc,nt,nd,ncor;    while(!p.empty())    {        P tmp=p.top();        p.pop();        for(int i=0; i<4; i++)        {            if(tmp.dir==i)            {                nr=tmp.r+dr[i];                nc=tmp.c+dc[i];                nt=tmp.Time+1;                nd=i;                ncor=(tmp.cor+1)%5;                if(!judge(nr,nc))                    continue;                if(Map[nr][nc]=='T'&&ncor==0)                    return nt;                else if(Map[nr][nc]!='#'&&vis[nr][nc][nd][ncor]==false)                {                    p.push(P(nr,nc,nt,nd,ncor));                    vis[nr][nc][nd][ncor]=true;                }            }            else            {                nt=tmp.Time+get_step(i,tmp.dir);                nd=i;                if(vis[tmp.r][tmp.c][nd][tmp.cor]==false)                {                    p.push(P(tmp.r,tmp.c,nt,nd,tmp.cor));                    vis[tmp.r][tmp.c][nd][tmp.cor]=true;                }            }        }    }    return 0;}int main(){    int min_t,cas=1;    while(~scanf("%d%d",&m,&n)&&m&&n)    {        init();        for(int i=0; i<m; i++)        {            scanf("%s",Map[i]);            for(int j=0; j<n; j++)            {                if(Map[i][j]=='S')                    p.push(P(i,j,0,0,0));            }        }        if(cas-1)            printf("\n");        if((min_t=bfs()))            printf("Case #%d\nminimum time = %d sec\n",cas++,min_t);        else            printf("Case #%d\ndestination not reachable\n",cas++);    }    return 0;}







0 0