题意:
解法:
直接bfs的复杂度是O ( n* m* k) 的,
但是如果我们能保证每个点都只被搜一次, 那么就可以变成O ( n* m) 的.
可以用set存为访问过的节点,
这样的话, 在bfs找后继的时候就不会访问已经走过的节点了,
总复杂度为O ( n* m* log) .
code:
# include <bits/stdc++.h>
# define PI pair< int , int >
using namespace std;
const int maxm= 1e3 + 5 ;
set< int > R[ maxm] ;
set< int > C[ maxm] ;
char s[ maxm] [ maxm] ;
int d[ maxm] [ maxm] ;
PI st, ed;
int n, m, k;
void bfs ( ) {
for ( int i= 1 ; i<= n; i++ ) {
for ( int j= 1 ; j<= m; j++ ) {
R[ i] . insert ( j) ;
C[ j] . insert ( i) ;
}
}
queue< PI> q;
q. push ( st) ;
for ( int i= 1 ; i<= n; i++ ) {
for ( int j= 1 ; j<= m; j++ ) {
d[ i] [ j] = - 1 ;
}
}
d[ st. first] [ st. second] = 0 ;
R[ st. first] . erase ( st. second) ;
C[ st. second] . erase ( st. first) ;
while ( q. size ( ) ) {
PI t= q. front ( ) ; q. pop ( ) ;
int x= t. first, y= t. second;
R[ x] . insert ( y) ;
vector< int > temp;
auto it= R[ x] . lower_bound ( y) ;
auto it2= it;
while ( 1 ) {
it2++ ;
if ( it2== R[ x] . end ( ) ) break ;
if ( s[ x] [ * it2] == '#' ) break ;
if ( * it2- y> k) break ;
temp. push_back ( * it2) ;
d[ x] [ * it2] = d[ x] [ y] + 1 ;
q. push ( { x, * it2} ) ;
}
it2= it;
while ( 1 ) {
if ( it2== R[ x] . begin ( ) ) break ;
it2-- ;
if ( s[ x] [ * it2] == '#' ) break ;
if ( y- * it2> k) break ;
temp. push_back ( * it2) ;
d[ x] [ * it2] = d[ x] [ y] + 1 ;
q. push ( { x, * it2} ) ;
}
R[ x] . erase ( y) ;
for ( auto i: temp) {
R[ x] . erase ( i) ;
C[ i] . erase ( x) ;
}
temp. clear ( ) ;
C[ y] . insert ( x) ;
it= C[ y] . lower_bound ( x) ;
it2= it;
while ( 1 ) {
it2++ ;
if ( it2== C[ y] . end ( ) ) break ;
if ( s[ * it2] [ y] == '#' ) break ;
if ( * it2- x> k) break ;
temp. push_back ( * it2) ;
d[ * it2] [ y] = d[ x] [ y] + 1 ;
q. push ( { * it2, y} ) ;
}
it2= it;
while ( 1 ) {
if ( it2== C[ y] . begin ( ) ) break ;
it2-- ;
if ( s[ * it2] [ y] == '#' ) break ;
if ( x- * it2> k) break ;
temp. push_back ( * it2) ;
d[ * it2] [ y] = d[ x] [ y] + 1 ;
q. push ( { * it2, y} ) ;
}
C[ y] . erase ( x) ;
for ( auto i: temp) {
R[ i] . erase ( y) ;
C[ y] . erase ( i) ;
}
}
}
void solve ( ) {
cin>> n>> m>> k;
for ( int i= 1 ; i<= n; i++ ) {
cin>> ( s[ i] + 1 ) ;
}
cin>> st. first>> st. second;
cin>> ed. first>> ed. second;
bfs ( ) ;
int ans= d[ ed. first] [ ed. second] ;
cout<< ans<< endl;
}
signed main ( ) {
ios:: sync_with_stdio ( 0 ) ; cin. tie ( 0 ) ;
solve ( ) ;
return 0 ;
}