zoukankan      html  css  js  c++  java
  • Gym

    题面

    题意:给你100个三维空间里的点,让你求一个点,使得他到所有点距离最大的值最小,也就是让你找一个最小的球覆盖掉这n个点

    题解:红书模板题,这题也因为数据小,精度也不高,所以也可以用随机算法,模拟退火之类的

      1 #include<bits/stdc++.h>
      2 using namespace std;
      3 int npoint,nouter;
      4 struct Tpoint
      5 {
      6     double x,y,z;
      7 };
      8 Tpoint pt[200000],outer[4],res;
      9 #define eps 1e-9
     10 double radius,tmp;
     11 inline double dist(Tpoint p1,Tpoint p2)
     12 {
     13     double dx=p1.x-p2.x,dy=p1.y-p2.y,dz=p1.z-p2.z;
     14     return (dx*dx+dy*dy+dz*dz);
     15 }
     16 inline double dot(Tpoint p1,Tpoint p2)
     17 {
     18     return p1.x*p2.x+p1.y*p2.y+p1.z*p2.z;
     19 }
     20 void ball()
     21 {
     22     Tpoint q[3];
     23     double m[3][3],sol[3],L[3],det;
     24     int i,j;
     25     res.x=res.y=res.z=radius=0;
     26     switch (nouter)
     27     {
     28         case 1:res=outer[0];break;
     29         case 2:
     30                res.x=(outer[0].x+outer[1].x)/2;
     31                res.y=(outer[0].y+outer[1].y)/2;
     32                res.z=(outer[0].z+outer[1].z)/2;
     33                radius=dist(res,outer[0]);
     34                break;
     35         case 3:
     36                for (int i=0;i<2;i++)
     37                {
     38                    q[i].x=outer[i+1].x-outer[0].x;
     39                    q[i].y=outer[i+1].y-outer[0].y;
     40                    q[i].z=outer[i+1].z-outer[0].z;
     41                }
     42                for (int i=0;i<2;i++) 
     43                    for (int j=0;j<2;j++)
     44                        m[i][j]=dot(q[i],q[j])*2;
     45                for (int i=0;i<2;i++) sol[i]=dot(q[i],q[i]);
     46                if (fabs(det=m[0][0]*m[1][1]-m[0][1]*m[1][0])<eps) return;
     47                L[0]=(sol[0] * m[1][1] - sol[1] * m[0][1])/det;
     48                L[1]=(sol[1] * m[0][0] - sol[0] * m[1][0])/det;
     49                res.x=outer[0].x+q[0].x*L[0]+q[1].x*L[1];
     50                res.y=outer[0].y+q[0].y*L[0]+q[1].y*L[1];
     51                res.z=outer[0].z+q[0].z*L[0]+q[1].z*L[1];
     52                radius=dist(res,outer[0]);
     53                break;
     54         case 4:
     55                for (int i=0;i<3;i++)
     56                {
     57                    q[i].x=outer[i+1].x-outer[0].x;
     58                    q[i].y=outer[i+1].y-outer[0].y;
     59                    q[i].z=outer[i+1].z-outer[0].z;
     60                    sol[i]=dot(q[i],q[i]);
     61                }
     62                for (int i=0;i<3;i++)
     63                    for (int j=0;j<3;j++) m[i][j]=dot(q[i],q[j])*2;
     64                det=m[0][0]*m[1][1]*m[2][2]
     65                   +m[0][1]*m[1][2]*m[2][0]
     66                   +m[0][2]*m[2][1]*m[1][0]
     67                   -m[0][1]*m[1][0]*m[2][2]
     68                   -m[0][2]*m[1][1]*m[2][0]
     69                   -m[0][0]*m[1][2]*m[2][1];
     70                if (fabs(det)<eps) return ;
     71                for (int j=0;j<3;j++)
     72                {
     73                    for (int i=0;i<3;i++) 
     74                        m[i][j]=sol[i];
     75                    L[j]=( m[0][0]*m[1][1]*m[2][2]
     76                          +m[0][1]*m[1][2]*m[2][0]
     77                         +m[0][2]*m[2][1]*m[1][0]
     78                        -m[0][2]*m[1][1]*m[2][0]
     79                    -m[0][1]*m[1][0]*m[2][2]
     80                     -m[0][0]*m[1][2]*m[2][1]       
     81                           )/det;
     82                    for  (int i=0;i<3;i++)
     83                        m[i][j]=dot(q[i],q[j])*2;
     84                 }
     85                 res=outer[0];
     86                 for (int i=0;i<3;i++)
     87                 {
     88                     res.x+=q[i].x*L[i];
     89                     res.y+=q[i].y*L[i];
     90                     res.z+=q[i].z*L[i];
     91                 }
     92                 radius=dist(res,outer[0]);
     93     }
     94 }
     95 void minball(int n)
     96 {
     97     ball();
     98     if (nouter<4)
     99     {
    100         for (int i=0;i<n;i++)
    101             if (dist(res,pt[i])-radius>eps)
    102             {
    103                 outer[nouter]=pt[i];
    104                 ++nouter;
    105                 minball(i);
    106                 --nouter;
    107                 if (i>0)
    108                 {
    109                     Tpoint Tt=pt[i];
    110                     memmove(&pt[1],&pt[0],sizeof(Tpoint)*i);
    111                     pt[0]=Tt;
    112                 }
    113             }
    114     }
    115 }
    116 int main()
    117 {
    118     radius=-1;
    119     scanf("%d",&npoint);
    120     for (int i=0;i<npoint;i++)
    121     {
    122         scanf("%lf%lf%lf",&pt[i].x,&pt[i].y,&pt[i].z);
    123     }
    124     for (int i=0;i<npoint;i++)
    125         if (dist(res,pt[i])-radius>eps)
    126         {
    127             nouter=1;
    128             outer[0]=pt[i];
    129             minball(i);
    130         }
    131     printf("%.10lf
    ",sqrt(radius));
    132 }
  • 相关阅读:
    darknet版本yolov3训练与测试
    Package opencv was not found in the pkg-config search path.
    ubuntu18.4下安装Anaconda及conda命令
    ubuntu18.4编译opencv4.1
    ubuntu18.4下cuda卸载
    抽象基类、访问控制与继承和继承中的类作用域
    C++ Pirmer : 第十五章 : 面向对象程序设计之基类和派生的定义、类型转换与继承与虚函数
    C++ Primer : : 第十四章 : 重载运算符与类型转换之类型转换运算符和重载匹配
    C++ Pirmer : 第十四章 : 重载运算符与类型转换之函数调用运算符与标准库的定义的函数对象
    C++ Primer : 第十四章 : 重载运算与类型转换之重载运算符
  • 原文地址:https://www.cnblogs.com/qywhy/p/10102466.html
Copyright © 2011-2022 走看看