hdu 3918 (Beiju)
来源:互联网 发布:调节色温的软件 编辑:程序博客网 时间:2024/05/16 19:16
题目大意:由两组从x轴向上延伸的相连线段(单调上升且互不相交)构成一个二维纸杯,其底为x轴,求其能装水的最大高度,这里不仅水不能溢出,而且还要考虑因重心与底的相对位置变化引起的翻到问题,即重心的x只能在底面的x左边范围之内、
解法:用一条与x轴平行的直线由底向上扫描,直到任意一段到达顶点或者重心x坐标超出,重心坐标超出的临界高度二分求出。
#include<cstdio>#include<cmath>#define eps 1e-8const int maxn=105;struct point{ double x,y; point(double xx=0,double yy=0){ x=xx;y=yy;}}left[maxn],right[maxn],list[5];int dcmp(double k){ return (k>eps)-(k<-eps);}double cross(point a,point b,point c){ return (c.x-a.x)*(b.y-a.y)-(b.x-a.x)*(c.y-a.y);}double area(point* p,int k){//多边形面积 double s1=0,s2=0; for(int i=0;i<k;i++) s1+=p[(i+1)%k].y*p[i].x,s2+=p[(i+1)%k].y*p[(i+2)%k].x; return fabs(s1-s2)/2;}point intersection(point u1,point u2,point v1,point v2){//直线交点 point ret=u1; double t=((u1.x-v1.x)*(v1.y-v2.y)-(u1.y-v1.y)*(v1.x-v2.x)) /((u1.x-u2.x)*(v1.y-v2.y)-(u1.y-u2.y)*(v1.x-v2.x)); ret.x+=(u2.x-u1.x)*t; ret.y+=(u2.y-u1.y)*t; return ret;}point gravity(point *p, int k){double area = 0;point center;center.x = 0;center.y = 0;for (int i = 0; i < k-1; i++){ area += (p[i].x*p[i+1].y - p[i+1].x*p[i].y)/2; center.x += (p[i].x*p[i+1].y - p[i+1].x*p[i].y) * (p[i].x + p[i+1].x); center.y += (p[i].x*p[i+1].y - p[i+1].x*p[i].y) * (p[i].y + p[i+1].y);}area += (p[k-1].x*p[0].y - p[0].x*p[k-1].y)/2;center.x += (p[k-1].x * p[0].y - p[0].x * p[k-1].y) * (p[k-1].x + p[0].x);center.y += (p[k-1].x * p[0].y - p[0].x * p[k-1].y) * (p[k-1].y + p[0].y);center.x /= 6*area;center.y /= 6*area;return center;}int n,m;point l_pre,r_pre,l_now,r_now;double x_pre,area_pre,x_now,area_now,xx;void init_now(){ list[0]=l_pre;list[1]=r_pre;list[2]=r_now;list[3]=l_now; area_now=area(list,4); x_now=gravity(list,4).x; xx=(x_pre*area_pre+x_now*area_now)/(area_pre+area_now);}bool ok(double xx){ return dcmp(xx-left[0].x)>=0&&dcmp(xx-right[0].x)<=0;}bool fun(double h){ point p1=point(l_pre.x,l_pre.y+h); point p2=point(r_pre.x,r_pre.y+h); l_now=intersection(l_pre,l_now,p1,p2); r_now=intersection(r_pre,r_now,p1,p2); init_now(); return ok(xx);}int ll,rr;void solve(){ ll=rr=0; area_pre=0; l_pre=left[0];r_pre=right[0]; while(ll<n-1&&rr<m-1){ int tl=ll+1,tr=rr+1; if(left[tl].y==right[tr].y){ ll=tl;rr=tr; l_now=left[tl];r_now=right[tr]; }else if(left[tl].y>right[tr].y){//左边高,取右边 rr=tr; r_now=right[rr]; l_now=intersection(left[ll],left[tl],r_now,point(r_now.x+1.0,r_now.y)); }else{//右边高,取左边 ll=tl; l_now=left[ll]; r_now=intersection(right[rr],right[tr],l_now,point(l_now.x+1.0,l_now.y)); } init_now(); if(ok(xx)){ l_pre=l_now;r_pre=r_now; x_pre=xx;area_pre+=area_now; }else{ double low=0,high=l_now.y-l_pre.y,mid; while(low+1e-6<high){ mid=(low+high)/2; if(fun(mid)) low=mid; else high=mid; } printf("%.3lf\n",l_pre.y+low); return; } } printf("%.3lf\n",l_pre.y);}int main(){ int ca; scanf("%d",&ca); while(ca--){ scanf("%d%d",&n,&m); for(int i=0;i<n;i++) scanf("%lf%lf",&left[i].x,&left[i].y); for(int i=0;i<m;i++) scanf("%lf%lf",&right[i].x,&right[i].y); solve(); } return 0;}
- hdu 3918 (Beiju)
- HDU--3918[Beiju] 几何模拟 二分
- BeiJu
- Broken Keyboard (a.k.a. Beiju Text)
- uestc oj 1276 Chiara’s “Beiju”
- Broken Keyboard (a.k.a. Beiju Text)
- UVA11988_Broken Keyboard (a.k.a. Beiju Text)
- Broken Keyboard (a.k.a. Beiju Text)
- UVA 11988 Broken Keyboard (Beiju Text)
- Broken Keyboard (a.k.a. Beiju Text)
- 11988 - Broken Keyboard (a.k.a. Beiju Text)
- Uva-11988-Broken Keyboard (a.k.a. Beiju Text)
- UVA 11988 Broken Keyboard (a.k.a. Beiju Text)
- uva 11988 Broken Keyboard (a.k.a. Beiju Text)
- UVA 11988 - Broken Keyboard (a.k.a. Beiju Text)
- UVA 11988 Broken Keyboard (a.k.a. Beiju Text)
- UVa11988-Broken Keyboard (a.k.a. Beiju Text)
- UVa:11988 Broken Keyboard (a.k.a. Beiju Text)
- lite源码阅读(六)总结
- AdvanceDateGrid编辑完成事件
- 弹弹堂中的弹坑效果
- 重构方法进阶(十一):代码常用重构方法(提取方法&将方法内联化)
- Emas快捷键之再学习02
- hdu 3918 (Beiju)
- wml页面传入url出现的问题
- Android手机开发:Dialog的使用
- 谷歌是如何做代码审查的
- 重构方法进阶(十三):代码常用重构方法(临时变量内联化&&拆分临时变量)
- 精通正则表达式
- Emas快捷键之再学习01
- 取WSUS客户端信息的代码
- 在android repo里添加一个新project