(1)求绕墙向左走,绕墙向右走,最短路分别是多少。前两个深搜,最后一个广搜(墙不能走)。
(2)本题的广搜是最基本的搜索,很简单。但我用了优先队列(虽然可以用,但并不需要),而且将优先队列写错了。。
friend bool operator <(node a, node b){ return a.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取余数。
具体代码:
View Code
#include#include #include 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 =0&&ty =0&&tx =0&&ty =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 =0&&ty 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