P1378 油滴扩展

原题连接

考察:dfs搜索

思路:

        注意这道题不能预处理每个圆覆盖的点及半径.假设我们先放a,a的半径为Ra,假设c点与a点距离>Ra但c的半径会受到a的覆盖范围的影响,也就是说Rc只能取dist-Ra.此时c的半径就和预处理的半径不同,不一定能覆盖预处理时判定能覆盖的点.

        所以这道题只能全排列时计算每一个点的半径.如果此点在已经选择的点的半径范围内,那么它的半径是0.否则取与长方形边框的距离,与其他已选择点的距离-Ri之间取最小值.

        x1,y1这种变量取名会编译错误......

请时刻牢记PI = acos(-1)

 1 #include <iostream>
 2 #include <cstring>
 3 #include <cmath>
 4 using namespace std;
 5 #define PI acos(-1) 
 6 const int N = 7;
 7 typedef pair<int,int> PII;
 8 int n,x1,x2,y1,y2; 
 9 double ans;
10 bool st[N];
11 struct Circle{
12     int x,y;
13     double r;
14 }cir[N]; 
15 double GetDist(int i,int j)
16 {
17     int x = abs(cir[i].x - cir[j].x);
18     int y = abs(cir[i].y - cir[j].y);
19     return sqrt(x*x+y*y);
20 }
21 double cal(int v)
22 {
23     double t1 = min(abs(cir[v].x-x1),abs(cir[v].x-x2));
24     double t2 = min(abs(cir[v].y-y1),abs(cir[v].y-y2));
25     double res = min(t1,t2);
26     for(int i=1;i<=n;i++)
27       if(v!=i&&st[i])//如果它在一个已选的点半径内. 
28       {
29           double dist = GetDist(i,v);
30           if(cir[i].r>dist) return 0;
31       }
32     for(int i=1;i<=n;i++)//只有已选的点才能限制它的半径. 
33       if(st[i]&&i!=v)
34           res = min(GetDist(i,v)-cir[i].r,res);
35     return res;
36 }
37 void dfs(double s,int cnt)
38 {//每个圆的半径都在变化,所以不能预处理 
39     if(cnt==n)
40     {
41         ans = max(s,ans);
42         return;
43     }
44     for(int i=1;i<=n;i++)
45       if(!st[i])
46       {
47           st[i] = 1;
48           cir[i].r = cal(i);
49           dfs(s+cir[i].r*cir[i].r*PI,cnt+1);
50           cir[i].r = 0;
51           st[i] = 0;
52       }
53 }
54 int main()
55 {
56     scanf("%d%d%d%d%d",&n,&x1,&y1,&x2,&y2);
57     for(int i=1;i<=n;i++)
58     {
59         int x,y; scanf("%d%d",&x,&y);
60         cir[i].x = x,cir[i].y = y;
61     }
62     dfs(0,0);
63     double s = abs(x1-x2)*abs(y1-y2);
64     int res = s-ans+0.5;
65     printf("%d\n",res);
66     return 0;
67 }

 

posted @ 2021-04-12 20:30  acmloser  阅读(55)  评论(0编辑  收藏  举报