http://poj.org/problem?id=3083
(1)求绕墙向左走,绕墙向右走,最短路分别是多少。前两个深搜,最后一个广搜(墙不能走)。
(2)本题的广搜是最基本的搜索,很简单。但我用了优先队列(虽然可以用,但并不需要),而且将优先队列写错了。。
friend bool operator <(node a, node b) { return a.step<b.step; }
这是求“最长路”,而不是求最短路。应该是:
friend bool operator <(node a, node b) { return a.step>b.step; }
(3)走路的顺序是有讲究的,在图上恰好是顺时针(或逆时针)一圈:
int dir[4][2]={-1,0,0,1,1,0,0,-1};
左是指前一次走的方向的左边,故有:
for(i=p-1;i<=p+2;i++) { j=(i%4+4)%4; ... }
同理,向右走是指前一次方向的右边:
for(i=p+1;i>=p-2;i--) { j=(i%4+4)%4; ... }
当然,衍生的写法还有很多种。这里有一种神奇的写法:
for(i=p-1;i<=p+2;i++) { j=(8+i)&3; ... }
虽然不容易懂,但本质上还是对4取余数。
具体代码:


#include<stdio.h> #include<string.h> #include<queue> using namespace std; char map[45][45]; int mark[45][45]; int px, py, ex, ey, pp, flag; int n, m, t; int dir[4][2]={-1,0,0,1,1,0,0,-1}; int left_step, right_step, min_step; struct node { int x, y, step, road; }e, s; void start() { int i; for(i=0;i<4;i++) { int tx, ty; tx=px+dir[i][0]; ty=py+dir[i][1]; if(tx>=0&&tx<n&&ty>=0&&ty<m&&map[tx][ty]!='#') {pp=i; break;} } } int dfs_left(int x, int y, int p) { int i, j; if(map[x][y]=='E') return 1; for(i=p-1;i<=p+2;i++) { j=((i%4)+4)%4; int tx, ty; tx=x+dir[j][0]; ty=y+dir[j][1]; if(tx>=0&&tx<n&&ty>=0&&ty<m&&map[tx][ty]!='#') { return 1+dfs_left(tx, ty, j); } } } int dfs_right(int x, int y, int p) { int i, j; if(map[x][y]=='E') return 1; for(i=p+1;i>=p-2;i--) { j=((i%4)+4)%4; int tx, ty; tx=x+dir[j][0]; ty=y+dir[j][1]; if(tx>=0&&tx<n&&ty>=0&&ty<m&&map[tx][ty]!='#') { return 1+dfs_right(tx, ty, j); } } } void bfs_min() { int i, j, k; memset(mark, 0, sizeof(mark)); queue<node>q; while(!q.empty()) q.pop(); e.x=px, e.y=py, e.step=1; q.push(e); while(!q.empty()) { e=q.front(); q.pop(); if(e.x==ex&&e.y==ey) break; for(i=0;i<4;i++) { s.x=e.x+dir[i][0]; s.y=e.y+dir[i][1]; s.step=e.step+1; if(s.x<0||s.x>=n||s.y<0||s.y>=m||map[s.x][s.y]=='#'||mark[s.x][s.y]) continue; q.push(s); mark[s.x][s.y]=1; } } min_step=e.step; } int main() { int i, j, k; while(scanf("%d", &t)!=EOF) { while(t--) { scanf("%d%d", &m, &n); for(i=0;i<n;i++) scanf("%s", &map[i]); for(i=0;i<n;i++) for(j=0;j<m;j++) { if(map[i][j]=='S') {px=i;py=j;} else if(map[i][j]=='E') {ex=i;ey=j;} } start(); left_step=dfs_left(px, py, pp); right_step=dfs_right(px, py, pp); bfs_min(); printf("%d %d %d\n", left_step, right_step, min_step); } } return 0; }