[三分套三分] 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 } 

猜你喜欢

转载自www.cnblogs.com/Comfortable/p/11376637.html