1. 题目
2. 题解
真 H2O
枚举 1 到 n 的排列,用 algorithm 自带的 next_permutation 函数即可。
对于一个排列,我们可以在 $n^2$的时间内算出该排列的答案。
具体看代码。
在下面的代码中,$judge(i,j)$返回当平面内只存在圆 $j$,圆 $i$的半径最大值。
如果圆 $j$覆盖了圆 $i$,返回 0。
如果圆 $j$只是一个点,返回 $inf$(即一个很大的数字)。
还有,$maxx,maxy,minx,miny$分别表示矩形框的右边、上边、左边、下边。
代码:
#include <bits/stdc++.h>
using namespace std;
typedef double DB;
int n,arr[10],ans=INT_MAX;
DB x[10],y[10],r[10],maxy,miny,minx,maxx,s;
DB judge(int a,int b)
{
if(a==b||r[b]<1e-10)return 1e10;
DB dis=sqrt((x[a]-x[b])*(x[a]-x[b])+(y[a]-y[b])*(y[a]-y[b]));
if(dis<=r[b])return 0;
return dis-r[b];
}
int main()
{
scanf("%d%lf%lf%lf%lf",&n,&minx,&maxy,&maxx,&miny);
if(minx>maxx)swap(minx,maxx);if(miny>maxy)swap(miny,maxy);
s=(maxy-miny)*(maxx-minx);
for(int i=1;i<=n;i++)scanf("%lf%lf",&x[i],&y[i]),arr[i]=i;
do
{
DB s2=s;
for(int i=1;i<=n;i++)
{
int f=arr[i];
r[f]=min(maxx-x[f],min(x[f]-minx,min(maxy-y[f],y[f]-miny)));
for(int j=1;j<=n;j++)r[f]=min(r[f],judge(f,j));
s2-=3.1415926*r[f]*r[f];
}
ans=min(ans,(int)round(s2));
}while(memset(r,0,sizeof(r)),next_permutation(arr+1,arr+1+n));
printf("%d\n",ans);
return 0;
}
2 条评论
boshi · 2017年5月13日 6:43 下午
这道题不是考过吗
konnyakuxzy · 2017年5月14日 1:08 下午
Orz 确实,而且我知道您当场AC了这题。。。
太强啦%%%%%%%%