Advertisement
BoxerTC

Zombie Blast

Oct 26th, 2014
214
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 3.87 KB | None | 0 0
  1. #include<bits/stdc++.h>
  2. using namespace std;
  3.  
  4. #define sc( x ) scanf( "%d" , &x )
  5. #define REP( i , n ) for( int i = 0 ; i < n ; ++i )
  6. #define clr( t , val ) memset( t , val , sizeof( t ) )
  7.  
  8. #define pb push_back
  9. #define all( v ) v.begin() , v.end()
  10. #define SZ( v ) ((int)(v).size())
  11.  
  12. #define mp make_pair
  13. #define fi first
  14. #define se second
  15.  
  16. #define N 2000
  17.  
  18. #define sqr(A) ((A)*(A))
  19. #define test puts( "********************test***************" );
  20.  
  21. typedef long long ll;
  22. double eps = 1e-8;
  23. int cmp (double a , double b = 0 ){
  24.         return a + eps < b ? -1 : a - eps > b ? 1 : 0 ;
  25. }
  26. struct point {
  27.     ll x , y ;
  28.     point ( ll a , ll b ) : x ( a ) , y ( b ){ }
  29.     point () {}
  30.     point operator + ( point p ){ return point ( x + p.x , y + p.y ) ; }
  31.     point operator - ( point p ){ return point ( x - p.x , y - p.y ) ; }
  32.     point operator * ( ll t ){ return point ( x * t , y * t ) ; }
  33.     double operator * ( point p ){ return x * p.x + y * p.y ; }
  34.     double operator % ( point p ){ return x * p.y - y * p.x ; }
  35.     bool operator == ( point p ){ return cmp ( x , p.x ) == 0 && cmp ( y , p.y ) == 0 ; }
  36.     bool operator < ( point p ) const{
  37.             int t = cmp ( x , p . x ) ;
  38.             if ( t ) return t < 0 ;
  39.             return cmp ( y , p . y ) < 0 ;
  40.     }
  41. } ;
  42. point T[ N * N + 5 ];
  43. int le[ N * N + 5 ] , ri[ N * N + 5 ];
  44. bool compx( const point &A , const point &B ){
  45.     return A.x < B.x;
  46. }
  47. bool compy( const point &A , const point &B ){
  48.     return A.y < B.y;
  49. }
  50.  
  51. //intervalocerrado[from,to]
  52. inline int make( int from , int to , bool byx = true ){
  53.     if( from > to ) return -1;
  54.     if( from == to ){
  55.         le[ from ] = ri[ from ] = -1;
  56.         return from;
  57.     }
  58.     int mid=(from + to)/2;
  59.     nth_element( T + from , T + mid , T + to + 1 , byx ? compx : compy );
  60.     le[ mid ] = make( from , mid - 1 , !byx );
  61.     ri[ mid ] = make( mid + 1 , to , !byx );
  62.     return mid;
  63. }
  64. /*
  65. inline int make( int from , int to , bool byx = true ){
  66.     if( from >= to ) return -1;
  67.     if( from + 1 == to ){
  68.         le[ from ] = ri[ from ] = -1;
  69.         return from;
  70.     }
  71.     int mid = (from + to)/2;
  72.     nth_element( T + from , T + mid , T + to , byx ? compx : compy );
  73.     le[ mid ] = make( from , mid , !byx );
  74.     ri[ mid ] = make( mid , to , !byx );
  75.     return mid;
  76. }
  77. */
  78. point p;
  79. ll dist;
  80.  
  81. //busco la distancia al nodo mas cercano de p.
  82. //dist tiene q ser puesta en inf antes de hacer la query.
  83. void query( int node , bool bxy ){
  84.     if( node == -1 ) return;
  85.     ll distnode = sqr( T[ node ].x - p.x ) + sqr( T[ node ].y - p.y );
  86.     dist = min( dist , distnode );
  87.     if( bxy ){
  88.         ll len = sqr( T[ node ].x - p.x );
  89.         if( compx( T[ node ] , p ) ){
  90.             query( ri[ node ] , !bxy );
  91.             if( len <= dist )
  92.                 query( le[ node ] , !bxy );
  93.         }else{
  94.             query( le[ node ] , !bxy );
  95.             if( len <= dist )
  96.                 query( ri[ node ] , !bxy );
  97.         }      
  98.     }else{
  99.         ll len = sqr( T[ node ].y - p.y );
  100.         if( compy( T[ node ] , p ) ){
  101.             query( ri[ node ] , !bxy );
  102.             if( len <= dist )
  103.                 query( le[ node ] , !bxy );
  104.         }else{
  105.             query( le[ node ] , !bxy );
  106.             if( len <= dist )
  107.                 query( ri[ node ] , !bxy );
  108.         }
  109.     }
  110. }
  111. char S[ N + 5 ][ N + 5 ];
  112. int main(){
  113.     int cases , n , m;
  114.     sc( cases );
  115.     REP( tc , cases ){
  116.         sc( m ) , sc( n );
  117.         REP( i , n ) scanf( "%s" , S[ i ] );
  118.         int len = 0;
  119.         REP( i , n )REP( j , m )
  120.             if( S[ i ][ j ] == 'M' ) {
  121.                 T[ len ++ ] = point( i , j );
  122.                 //cout << i << " " << j << endl;
  123.             }
  124.         int root = make( 0 , len );
  125.         ll ans = 0;
  126.         //cout << root << endl;
  127.         REP( i , n )REP( j , m )if( S[ i ][ j ] == 'Z' ){
  128.             dist = 1 << 30;
  129.             //cout << i << " " << j << endl;
  130.             p = point( i , j );
  131.             query( root , 1 );
  132.             //cout << dist << endl;
  133.             ans = max( ans , dist );
  134.         }
  135.         printf( "%.10f\n" , sqrt( ans ) );
  136.     }
  137.    
  138. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement