Section 3.3 - Camelot

  1  #include  < queue >
  2  #include  < iostream >
  3 
  4  using   namespace  std;
  5 
  6  struct  point {
  7       int  x, y;
  8      point  operator + ( const  point  & p)  const  {
  9          point np  =  { x  +  p.x, y  +  p.y };
 10           return  np;
 11      }
 12  }   ;
 13 
 14  int  r, c, knightsNum;
 15  point king, knights[ 30   *   26 ];
 16 
 17  const  point kinghtDir[ 8 =  {
 18      { - 2 + 1 }, { - 1 + 2 }, { + 1 + 2 }, { + 2 + 1 },
 19      { + 2 - 1 }, { + 1 - 2 }, { - 1 - 2 }, { - 2 - 1 }
 20  }   ;
 21 
 22  inline  bool  inside( const  point  & p) {
 23       return  p.x  >=   0   &&  p.x  <  r  &&  p.y  >=   0   &&  p.y  <  c;
 24  }
 25 
 26  int  dist[ 30 ][ 26 ][ 30 ][ 26 ];
 27  void  spfa( const  point  & s)
 28  {
 29       for  ( int  i  =   0 ; i  <  r; i ++ )
 30       for  ( int  j  =   0 ; j  <  c; j ++ )
 31          dist[s.x][s.y][i][j]  =  INT_MAX;
 32      dist[s.x][s.y][s.x][s.y]  =   0 ;
 33 
 34      queue < point >  q;
 35      q.push(s);
 36 
 37      point cp;    // current point
 38      point np;    // next point
 39       while  (q.empty()  ==   false )
 40      {
 41          cp  =  q.front(); q.pop();
 42           for  ( int  i  =   0 ; i  <   8 ; i ++ )
 43          {
 44              np  =  cp  +  kinghtDir[i];
 45               if  (inside(np)  &&  dist[s.x][s.y][cp.x][cp.y]  +   1   <  dist[s.x][s.y][np.x][np.y])
 46              {
 47                  dist[s.x][s.y][np.x][np.y]  =  dist[s.x][s.y][cp.x][cp.y]  +   1 ;
 48                  q.push(np);
 49              }
 50          }
 51      }
 52  }
 53 
 54  int  ans  =  INT_MAX;
 55  void  gather( int  tx,  int  ty)
 56  {
 57       int  sum  =   0 ;
 58       for  ( int  i  =   0 ; i  <  knightsNum; i ++ )
 59          sum  +=  dist[knights[i].x][knights[i].y][tx][ty];
 60 
 61       if  (sum  >  ans)
 62           return ;
 63 
 64       for  ( int  i  =  max( 0 , king.x  -   2 ); i  <=  min(r  -   1 , king.x  +   2 ); i ++ )
 65       for  ( int  j  =  max( 0 , king.y  -   2 ); j  <=  min(c  -   1 , king.y  +   2 ); j ++ )
 66      {
 67           int  tmp;
 68           if  (i  ==  king.x  &&  j  ==  king.y)
 69              tmp  =   0 ;
 70           else
 71          {
 72               if  (abs(i  -  king.x)  ==   1   ||  abs(j  -  king.y  ==   1 ))
 73                  tmp  =   1 ;
 74               else
 75                  tmp  =   2 ;
 76          }
 77           for  ( int  k  =   0 ; k  <  knightsNum; k ++ )
 78               if  (dist[knights[k].x][knights[k].y][i][j]  !=  INT_MAX  &&
 79                  dist[i][j][tx][ty]  !=  INT_MAX)
 80              ans  <?=  (sum  -  dist[knights[k].x][knights[k].y][tx][ty]
 81                   +  tmp  +  dist[knights[k].x][knights[k].y][i][j]  +  dist[i][j][tx][ty]);
 82      }
 83  }
 84 
 85  int  main()
 86  {
 87      freopen( " camelot.in " " r " , stdin);
 88      freopen( " camelot.out " " w " , stdout);
 89 
 90      cin  >>  r  >>  c;
 91 
 92      {
 93           char  a;  int  b;
 94          cin  >>  a  >>  b;
 95          king.y  =  a  -   ' A ' , king.x  =  b  -   1 ;
 96           while  (cin  >>  a  >>  b)
 97          {
 98              knights[knightsNum].y  =  a  -   ' A ' ;
 99              knights[knightsNum].x  =  b  -   1 ;
100              knightsNum ++ ;
101          }
102      }
103 
104       if  (knightsNum  ==   0 )
105      {
106          cout  <<   0   <<  endl;
107           return   0 ;
108      }
109 
110       for  ( int  i  =   0 ; i  <  r; i ++ )
111       for  ( int  j  =   0 ; j  <  c; j ++ )
112      {
113          point cp  =  { i, j };
114          spfa(cp);
115      }
116 
117       for  ( int  i  =   0 ; i  <  r; i ++ )
118       for  ( int  j  =   0 ; j  <  c; j ++ )
119          gather(i, j);
120 
121      cout  <<  ans  <<  endl;
122 
123       return   0 ;
124  }
125 

你可能感兴趣的:(Section 3.3 - Camelot)