bfs+priority_queue可过。就说些注意点: 1,priority_queue默认为升序,要重构"<"; 2,不要用vis[][]标记走过的点,因为有些点可能要多次访问; 3,方向相反时,当做一次转向。 #include<iostream> #include<string> #include<queue> using namespace std; #define maxn 80 int dir[][2]={{-1,0},{0,-1},{1,0},{0,1}}; char g[maxn][maxn],map[maxn][maxn]; int step[maxn][maxn]; int r,c; class node { public: int x,y; int path; int dir; }; bool operator<(const node &a,const node &b) { return a.path >b.path ; } void init() { int i,j; for(i=0;i<r;i++) gets(map[i]); for(i=0;i<=c+1;i++) g[0][i]=g[r+1][i]=' '; for(i=0;i<=r+1;i++) g[i][0]=g[i][c+1]=' '; for(i=0;i<r;i++) for(j=0;j<c;j++) g[i+1][j+1]=map[i][j]; } bool isok(int x,int y) { if(x>=0&&y>=0&&x<=r+1&&y<=c+1) return true; return false; } int solve(int x1,int y1,int x2,int y2) { for(int i=0;i<=r+1;i++) for(int j=0;j<=c+1;j++) step[i][j]=1e10; priority_queue<node >qu; int vis[maxn][maxn]; memset(vis,0,sizeof(vis)); vis[x1][y1]=1; for(int i=0;i<4;i++) { int tempx=x1+dir[i][0]; int tempy=y1+dir[i][1]; if(isok(tempx,tempy)) { if(tempx==x2&&tempy==y2) return 1; if(g[tempx][tempy]!='X') { node temp; temp.x =tempx;temp.y =tempy; vis[tempx][tempy]=1; temp.dir =i;temp.path =1; qu.push (temp); } } } int maxpath=1e10,nowpath; nowpath=maxpath; bool flag=false; while(!qu.empty ()) { node now=qu.top (); qu.pop (); if(now.path>nowpath) continue; for(int i=0;i<4;i++) { int tempx=now.x +dir[i][0]; int tempy=now.y +dir[i][1]; if(isok(tempx,tempy)) { node next; next.x =tempx;next.y =tempy; next.dir =i; if(next.dir ==now.dir ) next.path =now.path ; else next.path =now.path +1; if(next.x ==x2&&next.y ==y2) { if(next.path <nowpath) nowpath=next.path ; } else if(g[tempx][tempy]!='X'&&next.path <=nowpath&&step[tempx][tempy]>=next.path ) { step[tempx][tempy]=next.path ; qu.push (next); } } } } if(nowpath!=maxpath) return nowpath; return -1; } int main() { int Case =1; while(1) { cin>>c>>r; getchar(); if(c==0&&r==0) break; init(); printf("Board #%d:/n",Case++); int path=1; while(1) { int x1,x2,y1,y2; cin>>y1>>x1>>y2>>x2; if(x1+x2+y1+y2==0) break; int re=solve(x1,y1,x2,y2); if(re==-1) printf("Pair %d: impossible./n",path++); else printf("Pair %d: %d segments./n",path++,re); } printf("/n"); } return 0; }