//超级简单的水BFS,开小号刷WA。。最后静心检查原来是 n*m棋盘不是n*n。。 //找两点最短路,相邻两点有相同标记的耗时0,否则耗时1 //没什么特别的,最小优先队列直接水 #include <iostream> #include <queue> #include <cstdio> #include <cstring> #include <vector> using namespace std; int n,m,x1,y1,x2,y2; char s[510]; int a[] = { 1,-1,0,0 }; int b[] = { 0,0,1,-1 }; struct Node { int x,y,key,price; }node[510][510]; bool operator > ( Node a,Node b ) { return a.price > b.price; } priority_queue< Node,vector<Node>,greater<Node> > q; int main() { //freopen( "1.txt","r",stdin ); while( scanf("%d%d",&n,&m ) != EOF ) { int _sign = 2000000000; //搜索结束标记 for( int i = 0;i < n;i++ ) { scanf("%s",s); for( int j = 0;j < m;j++ ) { node[i][j].key = (( s[j] == '#' ) ? 1 : 0 ); node[i][j].price = 2000000000; node[i][j].x = i; node[i][j].y = j; } } scanf("%d%d%d%d",&x1,&y1,&x2,&y2); while( !q.empty() ) q.pop(); node[x1][y1].price = 0; q.push( node[x1][y1] ); while( !q.empty() ) { Node no = q.top(); q.pop(); if( node[no.x][no.y].price < no.price ) continue; //表示此点已经搜过更小的权 if( no.price > _sign ) break; //比先搜到的目标点权值大 结束 for( int i = 0; i < 4;i++ ) { int x3 = no.x + a[i]; int y3 = no.y + b[i]; if( x3 >= 0 && x3 < n && y3 >= 0 && y3 < m ) //水人,WA在这里。。 m写成n { int k; if( node[x3][y3].key == no.key ) k = no.price; else k = no.price + 1; if( x3 == x2 && y3 == y2 ) { _sign = min( k , _sign ); //快结束,但要考虑 还有 price的点没搜,可能比当前k小1 } if( node[x3][y3].price > k ) { node[x3][y3].price = k; q.push( node[x3][y3] ); } } } } cout<<node[x2][y2].price<<endl; } return 0; }