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 30 using 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,W int 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; }