ZOJ 3147 Dezider's Coverup【最小圆覆盖】【模板题】

本文介绍了一个寻找能够覆盖所有指定点的最小圆形区域的算法。该算法适用于需要确定最小覆盖范围的应用场景,例如在地图上找到覆盖多个地点的最小区域。通过输入一系列坐标点,算法可以计算出所需的最小圆形区域的半径。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Dezider's Coverup

Time Limit: 1 Second      Memory Limit: 32768 KB

Zlatica to his house for dinner. The trouble is, he tripped with the sauce in his hands (thankfully this was in the morning and Zlatica did not see it) and many bright red droplets fell on his white carpet. Now Dezider is starting to panic because he wants to have a perfectly clean house to impress Zlatica. Fortunately, there is a store nearby which sells all sizes of (expensive) circular rugs. Dezider does not have much money so he wants to buy the smallest rug with an integer radius which will cover all the droplets. You need to write a program to help him determine the right size to buy.

Input

Each test cases starts with one positive integer n, the number of droplets on the carpet. Each of the following n lines contains two floating-point numbers, separated by white space, which represent the x- and y-coordinate of the corresponding droplet.

Output

One line for each test case which consists of a single integer, the radius of the smallest circular rug needed to cover all the droplets.

Sample Input

4
1 -0.5
1.5 0
0.5 0.5
1 0.5

Sample Output

1

because a circular rug of radius 1 and center for example at 1,0 will cover the four droplets described by the input.


#include <stdio.h>
#include <math.h>
const int maxn=1005;
const double eps=1e-9;
struct point
{
    double x, y;
    point operator-(point & tp)
    {
        point rp;
        rp.x=x-tp.x;
        rp.y=y-tp.y;
        return rp;
    }
}p[maxn];
struct circle
{
    double r;
    point centre;
}c;
struct tripoint
{
    point t[3];
};
double dis(point a, point b)
{
    a=a-b;
    return sqrt(a.x * a.x + a.y * a.y);
}
double triangleArea(tripoint t)
{
    point p1, p2;
    p1=t.t[1]-t.t[0];
    p2=t.t[2]-t.t[0];
    return fabs(p1.x*p2.y-p1.y*p2.x)/2;
}
circle circumcircleOfTriangle(tripoint t)
{    //三角形的外接圆
    circle tmp;
    double a, b, c, c1, c2;
    double xA, yA, xB, yB, xC, yC;
    a=dis(t.t[0], t.t[1]);
    b=dis(t.t[1], t.t[2]);
    c=dis(t.t[2], t.t[0]);    //根据S = a * b * c / R / 4;求半径R
    tmp.r=a*b*c/triangleArea(t)/4;
    xA=t.t[0].x;
    yA=t.t[0].y;
    xB=t.t[1].x;
    yB=t.t[1].y;
    xC=t.t[2].x;
    yC=t.t[2].y;
    c1=(xA*xA+yA*yA-xB*xB-yB*yB)/2;
    c2=(xA*xA+yA*yA-xC*xC-yC*yC)/2;
    tmp.centre.x=(c1*(yA-yC)-c2*(yA-yB))/((xA-xB)*(yA-yC)-(xA-xC)*(yA-yB));
    tmp.centre.y=(c1*(xA-xC)-c2*(xA-xB))/((yA-yB)*(xA-xC)-(yA-yC)*(xA-xB));
    return tmp;
}
circle MinCircle2(int tce, tripoint ce)
{
    circle tmp;
    if(tce==0)
        tmp.r=-2;
    else if(tce==1)
    {
        tmp.centre=ce.t[0];
        tmp.r=0;
    }
    else if(tce==2)
    {
        tmp.r=dis(ce.t[0], ce.t[1])/2;
        tmp.centre.x=(ce.t[0].x+ce.t[1].x)/2;
        tmp.centre.y=(ce.t[0].y+ce.t[1].y)/2;
    }
    else if(tce==3)
        tmp=circumcircleOfTriangle(ce);
    return tmp;
}
void MinCircle(int t, int tce, tripoint ce)
{
    int i, j;
    point tmp;
    c=MinCircle2(tce, ce);
    if(tce==3) return;
    for(i=1; i<=t; i++)
    {
        if(dis(p[i], c.centre)>c.r)
        {
            ce.t[tce]=p[i];
            MinCircle(i-1, tce+1, ce);
            tmp=p[i];
            for(j=i; j>=2; j--)
                p[j]=p[j-1];
            p[1]=tmp;
        }
    }
}
int main()
{
    int n,i;
    while(~scanf("%d", &n) && n)
    {
        for(i=1; i<=n; i++)
            scanf("%lf%lf", &p[i].x, &p[i].y);
        tripoint ce;
        MinCircle(n, 0, ce);
        int x=(int)c.r;
        if(c.r-x<eps)
        {
            printf("%d\n",x);
        }
        else printf("%d\n",x+1);
    }
    return 0;
}







评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值