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;
}
分类: 文章

XZYQvQ

炒鸡辣鸡的制杖蒟蒻一枚QvQ

2 条评论

boshi · 2017年5月13日 6:43 下午

这道题不是考过吗

    konnyakuxzy · 2017年5月14日 1:08 下午

    Orz 确实,而且我知道您当场AC了这题。。。
    太强啦%%%%%%%%

发表回复

Avatar placeholder

您的电子邮箱地址不会被公开。 必填项已用 * 标注