• [三分套三分] Codeforces NEERC 13 E. Easy Geometry


    题目描述

    CJB小姐姐现在正在学几何。现在她遇到了一个问题,有人给了她一块凸多边形的蛋糕,放在她那带有坐标轴的桌子上。由于蛋糕很重,所以蛋糕无法旋转或者移动。CJB有强迫症,她只想吃矩形的蛋糕。所以她想把这样一块凸多边形的蛋糕裁剪成一个矩形。由于CJB有严重的强迫症,她认为不与坐标轴平行的矩形都是肮脏的,所以她想让你帮她裁剪一个面积最大的矩形蛋糕,且这个矩形的每条边均与坐标轴平行。

    题解

    • 首先矩形的宽度对答案是单峰的,固定宽度后发现左端点对最大面积也是单峰的,然后三分套三分就好了

    代码

     1 #include <cstdio>
     2 #include <iostream>
     3 #include <algorithm> 
     4 using namespace std;
     5 const int N=1e5+10;
     6 const double eps=1e-6;
     7 int L,R,n,cnta,cntb;
     8 double xl,yl,xr,yr,k;
     9 struct node
    10 {
    11     double x,y;
    12     node(double _x=0.0,double _y=0.0): x(_x),y(_y){}
    13     friend bool operator < (node a,node b){ return a.x<b.x; }
    14 }a[N],b[N],p[N];
    15 double dis(node a,node b,double x) { return a.y+(b.y-a.y)*(x-a.x)/(b.x-a.x); }
    16 node calc2(double x)
    17 {
    18     int p=upper_bound(a+1,a+cnta+1,node(x,0))-a,q=upper_bound(b+1,b+cntb+1,node(x,0))-b;
    19     p=min(p,cnta),q=min(q,cntb);
    20     return node(dis(a[p-1],a[p],x),dis(b[q-1],b[q],x));
    21 }
    22 double calc1(double x)
    23 {
    24     double rx=x+k;
    25     node tl=calc2(x),tr=calc2(rx);
    26     yl=max(tl.x,tr.x),yr=min(tl.y,tr.y);
    27     return yr-yl;
    28 }
    29 double calc(double x)
    30 {
    31     k=x; double l=p[L].x,r=p[R].x-x;
    32     while (r-l>eps) 
    33     {
    34         double midl=l+(r-l)/3.0,midr=r-(r-l)/3.0;
    35         if (calc1(midl)>calc1(midr)) r=midr; else l=midl;
    36     }
    37     xl=l,xr=xl+k; return calc1((l+r)*0.5)*k;
    38 }
    39 int main()
    40 {
    41     scanf("%d",&n);
    42     for (int i=1;i<=n;i++) scanf("%lf%lf",&p[i].x,&p[i].y);
    43     L=1,R=1;
    44     for (int i=1;i<=n;i++) 
    45     {
    46         if (p[i].x<p[L].x||(p[i].x==p[L].x&&p[i].y<p[L].y)) L=i;
    47         if (p[i].x>p[R].x||(p[i].x==p[R].x&&p[i].y<p[R].y)) R=i;
    48     }
    49     for (int i=L;i!=R;i=(i==1)?n:i-1) a[++cnta]=p[i]; a[++cnta]=p[R];
    50     L=1,R=1;
    51     for (int i=1;i<=n;i++) 
    52     {
    53         if (p[i].x<p[L].x||(p[i].x==p[L].x&&p[i].y>p[L].y)) L=i;
    54         if (p[i].x>p[R].x||(p[i].x==p[R].x&&p[i].y>p[R].y)) R=i;
    55     }
    56     for (int i=L;i!=R;i=(i==n)?1:i+1) b[++cntb]=p[i]; b[++cntb]=p[R];
    57     double l=0,r=p[R].x-p[L].x;
    58     while (r-l>eps)
    59     {
    60         double midl=l+(r-l)/3.0,midr=r-(r-l)/3.0;
    61         if (calc(midl)>calc(midr)) r=midr; else l=midl;
    62     }
    63     calc((l+r)*0.5),printf("%.10lf %.10lf %.10lf %.10lf",xl,yl,xr,yr);
    64 } 
  • 相关阅读:
    test20180922 倾斜的线
    test20180921 量子纠缠
    test20180921 手机信号
    test20180919 选择客栈
    BZOJ3083 遥远的国度
    test20180907 day1
    [ZJOI2010]基站选址
    HDU3584 Cube
    POJ2155 Matrix
    test20180902 day1
  • 原文地址:https://www.cnblogs.com/Comfortable/p/11376637.html
Copyright © 2020-2023  润新知