如果不考虑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
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