hdu 4617
来源:互联网 发布:淘宝快递费用价格表 编辑:程序博客网 时间:2024/06/05 20:16
题目
大意:3维空间中有n个圆柱,高为无限长,知道底面圆心,和半径,问是否会有两个圆柱,出现相交,如果没有,输出最少差多少相交。
想法:求出圆心的方向向量,这样就可以看成求出两个经过圆心的方向向量所在直线的距离,也就是异面直线的距离(参照:http://blog.csdn.net/zhuhuangjian/article/details/11739851),如果全部>ri+rj,则输出min(dis-ri-rj),否则Lucky;
#include<stdio.h>#include<string.h>#include<math.h>#include<algorithm>using namespace std;struct point{ double x,y,z; point(double _x=0,double _y=0,double _z=0) { x=_x;y=_y;z=_z; }};struct Vector { double x,y,z; Vector(double _x=0,double _y=0,double _z=0) { x=_x,y=_y,z=_z; }};struct plane // ax+by+cz+d=0;{ double a,b,c,d; plane(double _a=0,double _b=0,double _c=0,double _d=0) { a=_a,b=_b,c=_c,d=_d; }};Vector getvector(point a,point b)//直线的方向向量{ Vector ans=Vector(a.x-b.x,a.y-b.y,a.z-b.z); return ans;}Vector Common_Vertical_Line(Vector a,Vector b)//公垂线的方向向量 a*b { Vector ans=Vector(a.y*b.z-a.z*b.y,a.z*b.x-a.x*b.z,a.x*b.y-a.y*b.x); return ans;}double pointDis(Vector a)//点距离{ return sqrt((a.x*a.x+a.y*a.y+a.z*a.z));}plane getPlane(Vector a,Vector b,point c) //求由一直线的方向向量a,与一直线的方向向量b,与a上的一点c确定的平面;{ Vector line=Common_Vertical_Line(a,b); plane ans=plane(line.x,line.y,line.z,line.x*(-1)*c.x+line.y*(-1)*c.y+line.z*(-1)*c.z); return ans;}point getPoint(plane P,Vector B,point C)//C是B所在直线上的一点,求B所在直线和平面P的交点{ double k=((-1)*P.b*C.y-P.a*C.x-P.c*C.z-P.d)/(P.a*B.x+P.b*B.y+P.c*B.z); point ans=point(B.x*k+C.x,B.y*k+C.y,B.z*k+C.z); return ans;}inline double solve(Vector a,Vector b,Vector c,point x1,point x2){ plane a1=getPlane(a,c,x1); plane a2=getPlane(b,c,x2); point p1=getPoint(a1,b,x2); point p2=getPoint(a2,a,x1); Vector ans=getvector(p1,p2); return pointDis(ans);}int t,n;double x,y,z;int main(){ scanf("%d",&t); for(int ca=1;ca<=t;ca++) { scanf("%d",&n); point p[35][3]; double r[35]; Vector fa[35]; for(int i=1;i<=n;i++) { for(int j=0;j<3;j++) { scanf("%lf%lf%lf",&x,&y,&z); p[i][j]=point(x,y,z); } r[i]=pointDis(getvector(p[i][0],p[i][1])); fa[i]=Common_Vertical_Line(getvector(p[i][0],p[i][1]),getvector(p[i][1],p[i][2])); } double ans=100000000000000.0; for(int i=1;i<n;i++) { for(int j=i+1;j<=n;j++) { double temp=solve(fa[i],fa[j],Common_Vertical_Line(fa[i],fa[j]),p[i][0],p[j][0]); if(temp<=r[i]+r[j]) { ans=-1; break; } else ans=min(ans,temp-r[i]-r[j]); } } if(ans==-1) printf("Lucky\n"); else printf("%.2lf\n",ans); }}
- HDU 4617
- hdu 4617
- hdu 4617 : Weapon
- hdu 4617 Weapon
- hdu 4617 Weapon (几何)
- HDU 4617 Weapon
- HDU.4617 Weapon
- hdu
- hdu
- HDU
- hdu ()
- hdu
- hdu
- HDU
- HDU
- hdu
- hdu
- HDU
- ATL7中OBJECT_ENTRY_AUTO宏是如何实现com对象映射表
- Mac OS X的剪切操作
- ext4 grid 分页前台后台源码
- JSch - Java实现的SFTP(文件下载详解篇
- C/C++浮点数在内存中的存储方式
- hdu 4617
- 条件判断 & 循环语句的逆向
- KMP算法
- NSDate显示和时区的关系
- 黑马程序员<.net学习笔记--数据库>
- JNDI 是什么
- std::vector<T>的reserve()和resize()
- SQL函数:字符串中提取数字,英文,中文,过滤重复字符
- 百度的笔试题