• UVA 1473&LA 4986


    题意:给出空间内一些Z>0的点,保证有点不在Z轴上,求一个体积最小的包含所有点的圆锥,输出其h和r。

    思路:基本所有人都能想到二维化,问题就转化成了在第一象限内有一些y>0的点,用一条斜率<0的直线覆盖它们。很容易证明最优解的直线应该过其中一个或两个点,再推算一下可以得出,过点(x,y)的最优解为r = 1.5x,h = 3y,越接近它V越小。这样问题就简单明了了,先做一个凸包,再找出上凸包中斜率<0的边所过的点,枚举这些点的最优解就行了。

    做这题时WA了好几发,害得我以为是精度问题,后来才知道,是INF开小了(╯' - ')╯ ┻━┻ (掀桌子)。于是我把所有涉及精度的部分全还原了┬—┬ ノ( ' - 'ノ) (摆好摆好),发现跑出来时间还是242ms,(╯°Д°)╯ ┻━┻(再他妈的掀一次)。

     1 #include <cstdio>
     2 #include <cmath>
     3 #include <algorithm>
     4 using namespace std;
     5 #define N 10010
     6 struct Point{
     7     double x, y;
     8     Point(double _x = 0, double _y = 0):x(_x), y(_y){}
     9     Point operator-(const Point &P)const{ return Point(x-P.x, y-P.y); }
    10     bool operator< (const Point &p)const{ return (x<p.x||(x==p.x&&y<p.y)); }
    11 };
    12 double Cross(const Point &A, const Point &B){ return A.x*B.y-A.y*B.x; }
    13 Point p[N],ch[N];
    14 double a[N];
    15 double getx(Point A, Point B){
    16     return (A.x*B.y-B.x*A.y)/(B.y-A.y);
    17 }
    18 double gety(Point A, Point B){
    19     return (A.x*B.y-B.x*A.y)/(A.x-B.x);
    20 }
    21 int main(){
    22     int n,m,k,i;
    23     double x,y,z;
    24     while(~scanf("%d",&n)){
    25         for(i = 0; i < n; i++){
    26             scanf("%lf%lf%lf",&x,&y,&z);
    27             p[i].x = sqrt(x*x+y*y);
    28             p[i].y = z;
    29         }
    30         sort(p,p+n);
    31         m = 0;
    32         for(i = 0; i < n; i++){
    33             while(m>1 && Cross(ch[m-1]-ch[m-2],p[i]-ch[m-2]) <= 0) m--;
    34             ch[m++] = p[i];
    35         }
    36         k = m;
    37         for(i = n-2; i >= 0; i--){
    38             while(m>k && Cross(ch[m-1]-ch[m-2],p[i]-ch[m-2]) <= 0) m--;
    39             ch[m++] = p[i];
    40         }
    41         if(n > 1) m--;
    42         ch[m] = ch[0];
    43         double Min,r,h,R,H;
    44         Min = 8000000000000000000.0; a[k-1] = ch[k-1].x;
    45         for(i = k; i <= m; i++){
    46             if(ch[i].y <= ch[i-1].y) break;
    47             a[i] = getx(ch[i],ch[i-1]);
    48             if(1.5*ch[i-1].x < a[i-1])
    49                 r = a[i-1], h = gety(ch[i-1],Point(r,0));
    50             else if(1.5*ch[i-1].x <= a[i])
    51                 r = 1.5*ch[i-1].x, h = 3*ch[i-1].y;
    52             else r = a[i], h = gety(ch[i-1],Point(r,0));
    53             if(r*r*h < Min){
    54                 Min = r*r*h;
    55                 R = r; H = h;
    56             }
    57         }
    58         if(1.5*ch[i-1].x < a[i-1])
    59             r = a[i-1], h = gety(ch[i-1],Point(r,0));
    60         else r = 1.5*ch[i-1].x, h = 3*ch[i-1].y;
    61         if(r*r*h < Min){
    62             R = r; H = h;
    63         }
    64         printf("%.3lf %.3lf
    ",H,R);
    65     }
    66     return 0;
    67 }
  • 相关阅读:
    IOS Date, NSDateFormatter, compare, dateFromString:mydatestr
    IOS Retain,nil,alloc,init
    IOS NSArray,NSDictionary
    object c基础, 基本类型(NSString,char*NSDate,NSData),集合NSArray,NSMutableArray,NSDictionary,NSMutableDictionary,NSSet,NSMutableSet
    IOS UIProgressView 用法
    UIButton 用法
    XCode 快捷键,MAC 快捷键
    苹果软件系列产品介绍
    android 之多线程应用[message,messagequeue,handler,looper,asynchtask]
    Linux查看程序被哪个端口占用
  • 原文地址:https://www.cnblogs.com/lzxskjo/p/3351503.html
Copyright © 2020-2023  润新知