每次做这种题总是差一点,还是能力不够吧。。。需要用优先队列,这点我想到了,主要是没有想到利用一个vis数组,更新每个点的最短距离,贪心思想有问题。
#include<cstdio> #include<cstring> #include<iostream> #include<cmath> #include<queue> #define MAXD 1000 + 10 using namespace std; struct Point{ int x; int y; int d; Point(int a,int b,int c){ x = a; y = b ; d = c; } friend bool operator < (Point p,Point q){ if(p.d > q.d) return true; else return false; } }; int dir[][2] ={{-1,0},{-1,1},{0,1}, {1,1},{1,0},{1,-1}, {0,-1},{-1,-1}}; int n,m; int G[MAXD][MAXD]; int vis[MAXD][MAXD]; int dist[MAXD][MAXD]; int sx,sy,ex,ey; void solve(){ memset(vis,-1,sizeof(vis)); priority_queue<Point>q; q.push(Point(sx,sy,0)); vis[sx][sy] = 0; while(!q.empty()){ int x = q.top().x , y = q.top().y; int d = q.top().d; if(x == ex && y == ey){ printf("%d\n",d); return ; } q.pop(); int t = G[x][y]; for(int i = 0 ; i < 8; i++){ int nx = x + dir[i][0]; int ny = y + dir[i][1]; if(nx >=0 && nx < n && ny >= 0 && ny < m){ int _d; if(i == t) _d = d; else _d = d + 1; if(vis[nx][ny] == -1 || _d < vis[nx][ny]){ vis[nx][ny] = _d; q.push(Point(nx,ny,_d)); } } } } } int main(){ while(scanf("%d%d",&n,&m) != EOF){ for(int i = 0 ; i < n ; i++){ char str[MAXD]; scanf("%s",str); for(int j = 0 ; j < m ; j++) G[i][j] = str[j] - '0'; } int T; scanf("%d",&T); while(T--){ scanf("%d%d%d%d",&sx,&sy,&ex,&ey); sx -- ; sy -- ; ex -- ; ey--; solve(); } } return 0; }