题目
只要数学,贪心,几何和枚举学得好,这题就很简单。但是本菜鸡不行啊。
解决的方法是,先得到所有两点间的距离,接着排序,选取最短距离的两个点作为起点。
设已经停止增长的点集合为
V
1
V_{1}
V1,正在增长的点集合为
V
2
V_{2}
V2
对于一个点
a
a
a,计算与集合
V
1
V_{1}
V1所形成的圆的最短距离,以
V
1
V_{1}
V1中的某个点
b
b
b为例,两个点的距离为
d
a
b
=
(
x
a
−
x
b
)
2
+
(
y
a
−
y
b
)
2
d_{ab}=\sqrt{(x_{a}-x_{b})^{2}+(y_{a}-y_{b})^{2}}
dab=(xa−xb)2+(ya−yb)2,点
a
a
a所形成的圆的半径为
r
1
=
d
−
r
b
r_{1}=d-r_{b}
r1=d−rb
以
V
2
V_{2}
V2中的某个点
c
c
c为例,两点的距离为
d
a
c
=
(
x
a
−
x
c
)
2
+
(
y
a
−
y
c
)
2
d_{ac}=\sqrt{(x_{a}-x_{c})^{2}+(y_{a}-y_{c})^{2}}
dac=(xa−xc)2+(ya−yc)2,点
a
a
a所形成的圆的半径为
r
2
=
0.5
d
r_{2}=0.5d
r2=0.5d
对于点
a
a
a,比较该点与剩余的点中的
r
1
r_{1}
r1和
r
2
r_{2}
r2哪一个更小(第二次补题,依然败在这个上面),从而得到结果。当然,不论集合
V
1
V_{1}
V1和
V
2
V_{2}
V2的点都要进行这样的枚举,即为
n
−
1
n-1
n−1次(从整体情况上这么判断)
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const double PI=acos(-1.0);
const int N=2020;
struct node{
ll x, y;
double r;
bool vis;
}a[N];
struct link{
int index1, index2;
double dis;
bool flag;
};
double distance(node a, node b){
return sqrt(pow(a.x-b.x, 2)+pow(a.y-b.y, 2));
}
bool operator < (link a, link b){
return a.dis > b.dis;
}
int main()
{
int n;
scanf("%d", &n);
for(int i=1; i<=n; i++){
scanf("%lld%lld", &a[i].x, &a[i].y);
a[i].vis=false;
}
priority_queue<link> que;
link temp;
int cnt=0;
double ans=0;
for(int i=1; i<n; i++){
for(int j=i+1; j<=n; j++){
temp.index1=i, temp.index2=j;
temp.dis=distance(a[i], a[j])/2;
temp.flag=false;
que.push(temp);
}
}
while(cnt<n){
temp=que.top();
que.pop();
if(a[temp.index1].vis && a[temp.index2].vis){
continue;
} else if(a[temp.index1].vis){
if(temp.flag){
a[temp.index2].r=temp.dis;
ans+=PI*a[temp.index2].r*a[temp.index2].r;
a[temp.index2].vis=true;
cnt+=1;
} else {
temp.dis=distance(a[temp.index1], a[temp.index2])-a[temp.index1].r;
temp.flag=true;
que.push(temp);
}
} else if(a[temp.index2].vis){
if(temp.flag){
a[temp.index1].r=temp.dis;
ans+=PI*a[temp.index1].r*a[temp.index1].r;
a[temp.index1].vis=true;
cnt+=1;
} else {
temp.dis=distance(a[temp.index1], a[temp.index2])-a[temp.index2].r;
temp.flag=true;
que.push(temp);
}
} else {
a[temp.index1].r=a[temp.index2].r=temp.dis;
ans+=2*PI*a[temp.index1].r*a[temp.index1].r;
a[temp.index1].vis=true;
a[temp.index2].vis=true;
cnt+=2;
}
}
printf("%.15f\n", ans);
return 0;
}