PKU/POJ 3269 Building A New Barn

如果不考虑cannot be on any cow's grazing spot,容易证明分别求横竖的中位数就是最优解(若n是偶数的话解集就是一个矩形区间)。

现在只需要考虑解集被grazing spot占满的情况。由于题目说cows never graze in spots that are horizontally or vertically adjacent,那么被占满的情况就只有n是奇数的情况。于是分别固定一维,另一维在中位数前后两个数之间的区间就是满足条件的解。

 

 1  #include  < cstdio >
 2  #include  < algorithm >
 3  #include  < set >
 4  using   namespace  std;
 5 
 6  const   int  N  =   10000 ;
 7 
 8  struct  point
 9  {
10       int  x, y;
11  };
12 
13  int  n;
14  point p[N];
15  int  x[N], y[N];
16  int  x1, x2, y1, y2;
17  set < int >  table;
18 
19  inline  int  f( int  x,  int  y)
20  {
21       return  (x  +   10000 *   100000   +  (y  +   10000 );
22  }
23 
24  inline  bool  find( int  x,  int  y)
25  {
26       return  table.find(f(x, y))  !=  table.end();
27  }
28 
29  int  main()
30  {
31      scanf( " %d " & n);
32       for  ( int  i  =   0 ; i  <  n;  ++ i)
33      {
34          scanf( " %d%d " , x  +  i, y  +  i);
35          p[i].x  =  x[i];
36          p[i].y  =  y[i];
37          table.insert(f(x[i], y[i]));
38      }
39      sort(x, x  +  n);
40      sort(y, y  +  n);
41 
42       int  sum  =   0 , cnt  =   0 ;
43       if  (n  &   1 )
44      {
45          x1  =  x[n  /   2 ];
46          y1  =  y[n  /   2 ];
47           if  (find(x1, y1))
48          {
49               for  ( int  i  =   0 ; i  <  n;  ++ i)
50              {
51                  sum  +=  abs(x1  -  x[i]);
52                  sum  +=  abs(y1  -  y[i]);
53              }
54               ++ sum;
55 
56              x1  =  x[n  /   2   -   1 ];
57              x2  =  x[n  /   2   +   1 ];
58               for  ( int  i  =  x1; i  <=  x2;  ++ i)
59                   if  ( ! find(i, y1))
60                       ++ cnt;
61 
62              y1  =  y[n  /   2   -   1 ];
63              y2  =  y[n  /   2   +   1 ];
64               for  ( int  i  =  y1; i  <=  y2;  ++ i)
65                   if  ( ! find(x1, i))
66                       ++ cnt;
67          }
68           else
69          {
70               for  ( int  i  =   0 ; i  <  n;  ++ i)
71              {
72                  sum  +=  abs(x1  -  x[i]);
73                  sum  +=  abs(y1  -  y[i]);
74              }
75              cnt  =   1 ;
76          }
77      }
78       else
79      {
80          x1  =  x[n  /   2   -   1 ];
81          x2  =  x[n  /   2 ];
82          y1  =  y[n  /   2   -   1 ];
83          y2  =  y[n  /   2 ];
84          cnt  =  (x2  -  x1  +   1 *  (y2  -  y1  +   1 );
85           for  ( int  i  =   0 ; i  <  n;  ++ i)
86          {
87              sum  +=  abs(x1  -  x[i]);
88              sum  +=  abs(y1  -  y[i]);
89          }
90           for  ( int  i  =   0 ; i  <  n;  ++ i)
91          {
92               if  (p[i].x  >=  x1  &&  p[i].x  <=  x2  &&  p[i].y  >=  y1  &&  p[i].y  <=  y2)
93                   -- cnt;
94          }
95      }
96      printf( " %d %d\n " , sum, cnt);
97       return   0 ;
98  }
99 

 

 

你可能感兴趣的:(Build)