Blowing Candles (凸包的最小宽度 )


As Jacques-Édouard really likes birthday cakes, he celebrates his birthday every hour, instead of every year. His friends ordered him a round cake from a famous pastry shop, and placed candles on its top surface. The number of candles equals the age of Jacques-Édouard in hours. As a result, there is a huge amount of candles burning on the top of the cake. Jacques-Édouard wants to blow all the candles out in one single breath.
You can think of the flames of the candles as being points in the same plane, all within a disk of radius R (in nanometers) centered at the origin. On that same plane, the air blown by Jacques-Édouard follows a trajectory that can be described by a straight strip of width W, which comprises the area between two parallel lines at distance W, the lines themselves being included in that area. What is the minimum width W such that Jacques-Édouard can blow all the candles out if he chooses the best orientation to blow?

输入

The first line consists of the integers N and R, separated with a space, where N is Jacques-Édouard’s age in hours. Then N lines follow, each of them consisting of the two integer coordinates xi and yi of the ith candle in nanometers, separated with a space.
Limits

输出

Print the value W as a floating point number. An additive or multiplicative error of 10−5 is tolerated: if y is the answer, any number either within [y − 10−5,y + 10−5] or within [(1 − 10−5)y,(1 + 10−5)y] is accepted.

样例输入

3 10
0 0
10 0
0 10

样例输出

7.0710678118654755

题意:Jacques-Édouard要过生日,生日蛋糕上有很多个蜡烛,Jacques-Édouard想一口气把这个蛋糕上的蜡烛都吹灭,Jacques-Édouard吹的风的宽度是w,Jacques-Édouard可以选一个方向吹出宽为w的风,在这个范围内的蜡烛都会被吹灭。求这个最小宽度。

这个题目相当于求凸包的最小宽度

类似旋转卡壳,一边遍历凸包一边求距离当前边最远的点的距离,最后在这个最远距离里找出最小的一个就是结果。



#include<stdio.h>
#include<math.h>
#include<algorithm>
#include<iostream>
using namespace std;
typedef long long ll;
const int INF=0x3f3f3f3f;
struct point
{
    ll x,y;
}po[200015],index;
ll stack[200015],top;
  
ll cross(point p0,point p1,point p2)
{
    return (p1.x-p0.x)*(p2.y-p0.y)-(p1.y-p0.y)*(p2.x-p0.x);
}
  
double dis(point p1,point p2)
{
    return sqrt((double)(p2.x-p1.x)*(p2.x-p1.x)+(p2.y-p1.y)*(p2.y-p1.y));
}
  
bool cmp(point p1,point p2)
{
    ll tmp=cross(po[0],p1,p2);
    if(tmp>0)
        return true;
    else if(tmp==0&&dis(po[0],p1)<dis(po[0],p2))
        return true;
    else
        return false;
}
  
void init(int n)
{
    int i,k;
    point p0;
    scanf("%lld%lld",&po[0].x,&po[0].y);
    p0.x=po[0].x;
    p0.y=po[0].y;
    k=0;
    for(i=1;i<n;i++)
    {
        scanf("%lld%lld",&po[i].x,&po[i].y);
        if( (p0.y>po[i].y) || ((p0.y==po[i].y)&&(p0.x>po[i].x)) )
        {
            p0.x=po[i].x;
            p0.y=po[i].y;
            k=i;
        }
    }
    po[k]=po[0];
    po[0]=p0;
    sort(po+1,po+n,cmp);
}
  
void graham(int n)
{
    int i;
    if(n==1)
    {
        top=0;
        stack[0]=0;
    }
    if(n==2)
    {
        top=1;
        stack[0]=0;
        stack[1]=1;
    }
    if(n>2)
    {
        for(i=0;i<=1;i++)
            stack[i]=i;
        top=1;
        for(i=2;i<n;i++)
        {
            while(top>0&&cross(po[stack[top-1]],po[stack[top]],po[i])<=0)
                top--;
            top++;
            stack[top]=i;
        }
    }
}
double judge(int i,int k){
    int j=(i+1)%(top+1);
    double a,b,c;
    a=dis(po[stack[i]],po[stack[j]]);
    b=dis(po[stack[i]],po[stack[k]]);
    c=dis(po[stack[k]],po[stack[j]]);
    double q=(a+b+c)/2.0;
  
    return (double)sqrt(q*(q-a)*(q-b)*(q-c))/a*2.0;
}
  
int main()
{
    int n,R;
    scanf("%d",&n);
    scanf("%d",&R);
    init(n);
    graham(n);
    int index=2;
    double minn=INF*1.0;
    if(top<=1){
        printf("0\n");
        return 0;
    }
    for(int i=0;i<=top;i++)
    {
        double a1=judge(i,(index)%(top+1));
        while(1){
            double a2=judge(i,(index+1)%(top+1));
            if(a1>a2||index>2*top){
                if(a1<minn)
                    minn=a1;
                break;
            }
            index++;
            a1=a2;
        }
        if(index>2*top)
            break;
    }
    printf("%lf\n",minn);
    return 0;
}



猜你喜欢

转载自blog.csdn.net/sxh759151483/article/details/80155246