题目描述
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 }