zoukankan      html  css  js  c++  java
  • [三分套三分] 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 } 
  • 相关阅读:
    HAProxy、Keepalived 在 Ocatvia 的应用实现与分析
    Octavia 的 HTTPS 与自建、签发 CA 证书
    Octavia 创建 loadbalancer 的实现与分析
    OpenStack Rally 质量评估与自动化测试利器
    自建 CA 中心并签发 CA 证书
    Failed building wheel for netifaces
    通过 vSphere WS API 获取 vCenter Datastore Provisioned Space 置备空间
    OpenStack Placement Project
    我们建了一个 Golang 硬核技术交流群(内含视频福利)
    没有图形界面的软件有什么用?
  • 原文地址:https://www.cnblogs.com/Comfortable/p/11376637.html
Copyright © 2011-2022 走看看