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