洛谷P1378 油滴扩展
几个需要注意的点.
1. 按照你的算法, 当一个圆包含另一个圆的圆心时, 会出现半径是负数的情况吗?
2. 考虑了点在矩形外的情况吗?
3. 与四个边界比较了大小了吗?
4. 四舍五入了吗?
1 // luogu-judger-enable-o2
2 #include <cstdio>
3 #include <cstring>
4 #include <iostream>
5 #include <algorithm>
6 #include <cmath>
7 #include <vector>
8 using namespace std;
9 const int MAXN = 6 + 3;
10 const int INF = 0x3f3f3f3f;
11 const double PI = 3.1415926535;
12
13
14 struct point
15 {
16 double x, y, r;
17 }P[MAXN];
18
19 int N;
20 point S, T;
21 vector<point> order;
22
23 inline double dis(point p1, point p2){
24 return sqrt(pow(abs(p1.x - p2.x), 2) + pow(abs(p1.y - p2.y), 2));
25 }
26
27 double calc()
28 {
29 double siz = abs(S.x - T.x) * abs(S.y - T.y);
30 for(int i = 0; i < (int) order.size(); i++)
31 {
32 point *cur = &order[i];
33 cur->r = INF;
34 for(int j = 0; j < i; j++){
35 point *p = &order[j];
36 cur->r = min(cur->r, max(dis(*cur, *p) - p->r, 0.0));
37 }
38 cur->r = min(cur->r, min(min(abs(cur->x - S.x), abs(cur->y - S.y)),
39 min(abs(cur->x - T.x), abs(cur->y - T.y))));
40 siz -= (PI * pow(cur->r, 2));
41 }
42 return siz;
43 }
44
45 int cntp; bool vis[MAXN];
46 double ans;
47 void dfs(int cnt)
48 {
49 if(cnt == cntp + 1) return ans = min(calc(), ans), void();
50 for(int i = 1; i <= cntp; i++){
51 if(!vis[i]){
52 vis[i] = true;
53 order.push_back(P[i]);
54
55 dfs(cnt + 1);
56
57 order.pop_back();
58 vis[i] = false;
59 }
60 }
61
62 return ;
63 }
64
65 int main()
66 {
67 cin>>N;
68 scanf("%lf %lf %lf %lf", &S.x, &S.y, &T.x, &T.y);
69 if(S.x > T.x) swap(S, T);
70
71 cntp = 0; memset(vis, false, sizeof(vis));
72 for(int i = 1; i <= N; i++){
73 point p;
74 scanf("%lf %lf", &p.x, &p.y);
75 if(p.x < S.x || p.x > T.x || p.y < min(S.y, T.y) || p.y > max(S.y, T.y)) continue;
76 P[++cntp] = p;
77 }
78
79 ans = abs(S.x - T.x) * abs(S.y - T.y);
80 dfs(1);
81
82 cout<<((int) (ans + 0.5))<<endl;
83 return 0;
84 }