题意:有一个迷宫,然后起点和终点在四边上,然后边上除了起点和终点都是墙,从s走到e有三种策略,第一种,左手摸墙策略:左手放在墙壁上,然后手不离墙壁,沿着大拇指方向走,必定能走到终点,然后计算这种走法的步数。第二种,右手摸墙策略:右手放在墙壁上,然后手不离墙壁,沿着大拇指方向走,必定能走到终点,然后计算这种走法的不熟。第三种,最短路径。
然后输出三种策略的行走长度。
思想:首先,直接先点名一个坑点,如果无法从s走到e直接不输出,虽然题目中表明了,总能从s走到e。
其次,s走到e,左手扶墙策略和从e走到s,右手扶墙策略是一回事。
最后,就是主要步骤了,先规定方向:上0右1下2左3,然后dir方向数组也要按照上右下左存储。
当按照原来方向向前一步走,如果此时的左手边是墙,那么就保持方向不变,继续前行;
当按照原来方向向前一步走,如果此时的左手边不是墙,那么显然就要进行左转弯,改变方向为(原来方向 + 3) % 4,然后再在转向后向前一步走;
当按照原来方向向前一步走,如果走到了墙上,也就是不能走了,就要进行右转弯,改变方向为(原来方向 + 1) % 4,不用走动,转向即可。
按照上述三种情况,采用队列结构即可。至于最短路非常简单BFS搜到即可输出。
//直走,左前方有wall,启动直走 //直走,左前方没有wall,启动左转 //直走,前方有wall,启动右转 //上0下2左3右1 #include<stdio.h> #include<string.h> #include<queue> using namespace std; int h,w; char map[45][45]; struct NODE{ int x,y; int dir; int steps; }; struct NODE s_node,e_node; int dir[4][2] = {-1,0,0,1,1,0,0,-1}; int WalkBFS() { struct NODE node = s_node; int minstep = 0; bool visit[45][45]; queue<NODE>q; while(!q.empty()) q.pop(); memset(visit,false,sizeof(visit)); visit[node.x][node.y] = true; node.steps = 1; q.push(node); while(!q.empty()){ node = q.front(); q.pop(); for(int k = 0;k <= 3; ++k){ NODE nxt_node; nxt_node.x = node.x + dir[k][0]; nxt_node.y = node.y + dir[k][1]; if(map[nxt_node.x][nxt_node.y] == '.' && nxt_node.x >= 1 && nxt_node.x <= h && nxt_node.y >= 1 && node.y <= w && !visit[nxt_node.x][nxt_node.y]){ //printf("(%d,%d)\n",nxt_node.x,nxt_node.y); nxt_node.steps = node.steps + 1; visit[nxt_node.x][nxt_node.y] = true; if(nxt_node.x == e_node.x && nxt_node.y == e_node.y){ return nxt_node.steps; } q.push(nxt_node); } } } return -1; } void PUT(int x,int y,int dir) { char str[10]; if(dir == 0) strcpy(str,"上"); else if(dir == 1) strcpy(str,"右"); else if(dir == 2) strcpy(str,"下"); else strcpy(str,"左"); printf("(%d,%d,%s)\n",x,y,str); } int Walk_LEFT_BFS(int MARK) { NODE snode,enode; queue<NODE>q; while(!q.empty()) q.pop(); if(MARK){ snode = s_node; enode = e_node; } else{ snode = e_node; enode = s_node; } snode.steps = 1; q.push(snode); while(!q.empty()){ snode = q.front(); q.pop(); //PUT(snode.x,snode.y,snode.dir); if(snode.x == enode.x && snode.y == enode.y){ return snode.steps; } NODE nxtnode; nxtnode.x = snode.x + dir[snode.dir][0]; nxtnode.y = snode.y + dir[snode.dir][1]; if(map[nxtnode.x][nxtnode.y] == '#'){ snode.dir = (snode.dir + 1) % 4;//TURN RIGHT q.push(snode); } else if(map[nxtnode.x][nxtnode.y] == '.' && map[nxtnode.x + dir[(snode.dir + 3) % 4][0]][nxtnode.y + dir[(snode.dir + 3) % 4][1]] == '#'){ nxtnode.dir = snode.dir; nxtnode.steps = snode.steps + 1; q.push(nxtnode); } else if(map[nxtnode.x][nxtnode.y] == '.' && map[nxtnode.x + dir[(snode.dir + 3) % 4][0]][nxtnode.y + dir[(snode.dir + 3) % 4][1]] == '.'){ nxtnode.dir = (snode.dir + 3) % 4;//TURN LEFT //左转 nxtnode.x += dir[nxtnode.dir][0]; nxtnode.y += dir[nxtnode.dir][1]; nxtnode.steps = snode.steps + 2; q.push(nxtnode); } } return -1; } int main() { int T; scanf("%d",&T); while(T--){ memset(map,'\0',sizeof(map)); scanf("%d%d",&w,&h); for(int i = 1;i <= h; ++i){ scanf("%s",map[i]+1); } for(int i = 1;i <= h; ++i){ for(int j = 1;j <= w; ++j){ if(map[i][j] == 'S'){ map[i][j] = '.'; s_node.x = i; s_node.y = j; if(i == 1){ s_node.dir = 2; } else if(i == h){ s_node.dir = 0; } else if(j == 1){ s_node.dir = 1; } else if(j == w){ s_node.dir = 3; } } if(map[i][j] == 'E'){ map[i][j] = '.'; e_node.x = i; e_node.y = j; if(i == 1){ e_node.dir = 2; } else if(i == h){ e_node.dir = 0; } else if(j == 1){ e_node.dir = 1; } else if(j == w){ e_node.dir = 3; } } } } int lft_step = Walk_LEFT_BFS(1); int rht_step = Walk_LEFT_BFS(0); int min_step = WalkBFS(); //printf("%d\n",min_step); if(lft_step == -1) continue; printf("%d %d %d\n",lft_step,rht_step,min_step); } return 0; } /* 2 8 8 ######## #......# #.####.# #.####.# #.####.# #.####.# #...#..# #S#E#### 9 5 ######### #.#.#.#.# S.......E #.#.#.#.# ######### */