UVA 1473&LA 4986 - Dome of Circus
2013-10-04 14:44
387 查看
题意:给出空间内一些Z>0的点,保证有点不在Z轴上,求一个体积最小的包含所有点的圆锥,输出其h和r。
思路:基本所有人都能想到二维化,问题就转化成了在第一象限内有一些y>0的点,用一条斜率<0的直线覆盖它们。很容易证明最优解的直线应该过其中一个或两个点,再推算一下可以得出,过点(x,y)的最优解为r = 1.5x,h = 3y,越接近它V越小。这样问题就简单明了了,先做一个凸包,再找出上凸包中斜率<0的边所过的点,枚举这些点的最优解就行了。
做这题时WA了好几发,害得我以为是精度问题,后来才知道,是INF开小了(╯' - ')╯ ┻━┻ (掀桌子)。于是我把所有涉及精度的部分全还原了┬—┬ ノ( ' - 'ノ) (摆好摆好),发现跑出来时间还是242ms,(╯°Д°)╯ ┻━┻(再他妈的掀一次)。
思路:基本所有人都能想到二维化,问题就转化成了在第一象限内有一些y>0的点,用一条斜率<0的直线覆盖它们。很容易证明最优解的直线应该过其中一个或两个点,再推算一下可以得出,过点(x,y)的最优解为r = 1.5x,h = 3y,越接近它V越小。这样问题就简单明了了,先做一个凸包,再找出上凸包中斜率<0的边所过的点,枚举这些点的最优解就行了。
做这题时WA了好几发,害得我以为是精度问题,后来才知道,是INF开小了(╯' - ')╯ ┻━┻ (掀桌子)。于是我把所有涉及精度的部分全还原了┬—┬ ノ( ' - 'ノ) (摆好摆好),发现跑出来时间还是242ms,(╯°Д°)╯ ┻━┻(再他妈的掀一次)。
#include <cstdio> #include <cmath> #include <algorithm> using namespace std; #define N 10010 struct Point{ double x, y; Point(double _x = 0, double _y = 0):x(_x), y(_y){} Point operator-(const Point &P)const{ return Point(x-P.x, y-P.y); } bool operator< (const Point &p)const{ return (x<p.x||(x==p.x&&y<p.y)); } }; double Cross(const Point &A, const Point &B){ return A.x*B.y-A.y*B.x; } Point p ,ch ; double a ; double getx(Point A, Point B){ return (A.x*B.y-B.x*A.y)/(B.y-A.y); } double gety(Point A, Point B){ return (A.x*B.y-B.x*A.y)/(A.x-B.x); } int main(){ int n,m,k,i; double x,y,z; while(~scanf("%d",&n)){ for(i = 0; i < n; i++){ scanf("%lf%lf%lf",&x,&y,&z); p[i].x = sqrt(x*x+y*y); p[i].y = z; } sort(p,p+n); m = 0; for(i = 0; i < n; i++){ while(m>1 && Cross(ch[m-1]-ch[m-2],p[i]-ch[m-2]) <= 0) m--; ch[m++] = p[i]; } k = m; for(i = n-2; i >= 0; i--){ while(m>k && Cross(ch[m-1]-ch[m-2],p[i]-ch[m-2]) <= 0) m--; ch[m++] = p[i]; } if(n > 1) m--; ch[m] = ch[0]; double Min,r,h,R,H; Min = 8000000000000000000.0; a[k-1] = ch[k-1].x; for(i = k; i <= m; i++){ if(ch[i].y <= ch[i-1].y) break; a[i] = getx(ch[i],ch[i-1]); if(1.5*ch[i-1].x < a[i-1]) r = a[i-1], h = gety(ch[i-1],Point(r,0)); else if(1.5*ch[i-1].x <= a[i]) r = 1.5*ch[i-1].x, h = 3*ch[i-1].y; else r = a[i], h = gety(ch[i-1],Point(r,0)); if(r*r*h < Min){ Min = r*r*h; R = r; H = h; } } if(1.5*ch[i-1].x < a[i-1]) r = a[i-1], h = gety(ch[i-1],Point(r,0)); else r = 1.5*ch[i-1].x, h = 3*ch[i-1].y; if(r*r*h < Min){ R = r; H = h; } printf("%.3lf %.3lf\n",H,R); } return 0; }
相关文章推荐
- UVALive 4986 Dome of Circus(三分、凸包、凸性函数)
- G - Dome of Circus UVALive - 4986 (三分)
- HDU 3756,LA 4986——Dome of Circus
- 【treap tree】 HDOJ 3726 && LA 5031 && UVA 1479 Graph and Queries
- 圆弧并 uva 10969 && LA 2572
- poj 1873 && uva 811 && la 5211
- hdu 4081 && uva 1494 && LA 5713 Qin Shi Huang's National Road System
- UVa 1473 Dome of Circus(求凸包)
- UVa 1473 - Dome of Circus 三分
- UVA 1401 Remember the Word & LA 3942
- UVA 1401 & LA 3942 (字典树Trie+递推)
- poj 1017 && uva 311 && la 5526
- UVA 1267 && LA 3902 Network (思路--树上的DFS)
- LA 3942 && UVa 1401 Remember the Word (Trie + DP)
- Dome of Circus - UVa 1473 几何 凸包
- poj 1328 && uva 1193 && la 2519
- 圆锥:转为平面几何 UVA 1473 Dome of Circus
- poj 1042 && uva 757 && la 5422
- uva 1473 - Dome of Circus (几何 + 二分)
- UVA 1401 & LA 3942 Remember the Word 字典树+DP