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