Problem Description
  Doctor D. are researching for a horrific weapon. The muzzle of the weapon is a circle. When it fires, rays form a cylinder that runs through the circle verticality in both side. If one cylinder of rays touch another, there will be an horrific explosion. Originally, all circles can rotate easily. But for some unknown reasons they can not rotate any more. If these weapon can also make an explosion, then Doctor D. is lucky that he can also test the power of the weapon. If not, he would try to make an explosion by other means. One way is to find a medium to connect two cylinder. But he need to know the minimum length of medium he will prepare. When the medium connect the surface of the two cylinder, it may make an explosion.
 
Input
  The first line contains an integer T, indicating the number of testcases. For each testcase, the first line contains one integer N(1 < N < 30), the number of weapons. Each of the next 3N lines  contains three float numbers. Every 3 lines represent one weapon. The first line represents the coordinates of center of the circle, and the second line and the third line represent two points in the circle which surrounds the center. It is supposed that these three points are not in one straight line. All float numbers are between -1000000 to 1000000.
 
Output
  For each testcase, if there are two cylinder can touch each other, then output 'Lucky', otherwise output then minimum distance of any two cylinders, rounded to two decimals, where distance of two cylinders is the minimum distance of any two point in the surface of two cylinders.
 
题目大意:给多个圆柱,若有任意两个圆柱相交,则输出Lucky,否则输出两个圆柱间的最短距离。
思路:已经算是模板题了,不多解释。
 
代码(0MS):
 #include <cstdio>
#include <algorithm>
#include <cstring>
#include <iostream>
#include <cmath>
using namespace std;
typedef long long LL; const double EPS = 1e-;
const double INF = 1e50;
const double PI = acos(-1.0); inline int sgn(double x) {
return (x > EPS) - (x < EPS);
} struct Point3D {
double x, y, z;
Point3D() {}
Point3D(double x, double y, double z): x(x), y(y), z(z) {}
void read() {
scanf("%lf%lf%lf", &x, &y, &z);
}
double operator * (const Point3D &rhs) const {
return x * rhs.x + y * rhs.y + z * rhs.z;
}
Point3D operator + (const Point3D &rhs) const {
return Point3D(x + rhs.x, y + rhs.y, z + rhs.z);
}
Point3D operator - (const Point3D &rhs) const {
return Point3D(x - rhs.x, y - rhs.y, z - rhs.z);
}
double length() const {
return sqrt(x * x + y * y + z * z);
}
}; struct Line3D {
Point3D st, ed;
Line3D() {}
Line3D(Point3D st, Point3D ed): st(st), ed(ed) {}
}; struct Plane3D {
Point3D a, b, c;
Plane3D() {}
Plane3D(Point3D a, Point3D b, Point3D c): a(a), b(b), c(c) {}
void read() {
a.read(), b.read(), c.read();
}
}; double dist(const Point3D &a, const Point3D &b) {
return (a - b).length();
}
//叉积
Point3D cross(const Point3D &u, const Point3D &v) {
Point3D ret;
ret.x = u.y * v.z - u.z * v.y;
ret.y = u.z * v.x - u.x * v.z;
ret.z = u.x * v.y - u.y * v.x;
return ret;
}
//点到直线距离
double point_to_line(const Point3D &p, const Line3D &l) {
return cross(p - l.st, l.ed - l.st).length() / dist(l.ed, l.st);
}
//求两直线间的距离
double line_to_line(const Line3D u, const Line3D v) {
Point3D n = cross(u.ed - u.st, v.ed - v.st);
return fabs((u.st - v.st) * n) / n.length();
}
//取平面法向量
Point3D vector_of_plane(const Plane3D &s) {
return cross(s.a - s.b, s.b - s.c);
}
//判断两直线是否平行
bool isParallel(const Line3D &u, const Line3D &v) {
return sgn(cross(u.ed - u.st, v.ed - v.st).length()) <= ;
} const int MAXN = ; Plane3D s[MAXN];
Line3D l[MAXN];
double r[MAXN];
int T, n; int main() {
scanf("%d", &T);
while(T--) {
scanf("%d", &n);
for(int i = ; i < n; ++i) s[i].read();
for(int i = ; i < n; ++i) {
Point3D v = vector_of_plane(s[i]);
l[i] = Line3D(s[i].a, s[i].a + v);
r[i] = dist(s[i].a, s[i].b);
}
double ans = INF;
for(int i = ; i < n; ++i) {
for(int j = i + ; j < n; ++j) {
double d;
if(isParallel(l[i], l[j])) d = point_to_line(l[i].st, l[j]);
else d = line_to_line(l[i], l[j]);
ans = min(ans, d - r[i] - r[j]);
}
}
if(sgn(ans) <= ) puts("Lucky");
else printf("%.2f\n", ans);
}
}

HDU 4617 Weapon(三维几何)的更多相关文章

  1. HDU 4617 Weapon 三维计算几何

    题意:给你一些无限长的圆柱,知道圆柱轴心直线(根据他给的三个点确定的平面求法向量即可)与半径,判断是否有圆柱相交.如果没有,输出柱面最小距离. 一共只有30个圆柱,直接暴力一下就行. 判相交/相切:空 ...

  2. hdu 4617 Weapon【异面直线距离——基础三维几何】

    链接: http://acm.hdu.edu.cn/showproblem.php?pid=4617 Weapon Time Limit: 3000/1000 MS (Java/Others)     ...

  3. hdu 4617 Weapon

    http://acm.hdu.edu.cn/showproblem.php?pid=4617 三维几何简单题 多谢高尚博学长留下的模板 代码: #include <iostream> #i ...

  4. HDU 4617 Weapon (简单三维计算几何,异面直线距离)

    Weapon Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 65535/32768 K (Java/Others)Total Subm ...

  5. hdu 4617 Weapon(叉积)

    大一学弟表示刚学过高数,轻松无压力. 我等学长情何以堪= = 求空间无限延伸的两个圆柱体是否相交,其实就是叉积搞一搞 详细点就是求两圆心的向量在两直线(圆心所在的直线)叉积上的投影 代码略挫,看他的吧 ...

  6. hdu 5839(三维几何)

    Special Tetrahedron Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Othe ...

  7. POJ 3528--Ultimate Weapon(三维凸包)

    Ultimate Weapon Time Limit: 2000MS   Memory Limit: 131072K Total Submissions: 2430   Accepted: 1173 ...

  8. HDU - 3584 Cube (三维树状数组 + 区间改动 + 单点求值)

    HDU - 3584 Cube Time Limit: 1000MS   Memory Limit: 65536KB   64bit IO Format: %I64d & %I64u Subm ...

  9. HDU 3584 Cube --三维树状数组

    题意:给一个三维数组n*n*n,初始都为0,每次有两个操作: 1. 翻转(x1,y1,z1) -> (x2,y2,z2) 0. 查询A[x][y][z] (A为该数组) 解法:树状数组维护操作次 ...

随机推荐

  1. angular动态绑定样式以及改变UI框架样式的方法

    一:angular动态绑定样式 举个栗子: <tr *ngFor="let dataTr of tableData;let i = index" [formGroupName ...

  2. 阿里云centOS7.4上MySql5.6安装

    最近一个项目要部署在阿里云上,为了开发团队方便,我自费买了个ECS,先装个数据库给开发用. 因为之前都是在真机安装,与这次阿里云上的部署比起来,还是有点区别的. Mysql 1 安装mysql版本包 ...

  3. 关于Django中JsonResponse返回中文字典编码错误的解决方案

    解决方案:JsonResponse(data, json_dumps_params={'ensure_ascii':False}) ! data是需要渲染的字典 def master(request) ...

  4. memcache和redis的区别和联系

    一.区别 Memcache : 1,对每个key的数据最大是1M. 2,对各种技术支持比较全面,session可以存储memcache中,各种框架(例如thinkphp)对memcache支持比较好. ...

  5. java并发实战:连接池实现

    池化技术简介 在我们使用数据库的过程中,我们往往使用数据库连接池而不是直接使用数据库连接进行操作,这是因为每一个数据库连接的创建和销毁的代价是昂贵的,而池化技术则预先创建了资源,这些资源是可复用的,这 ...

  6. 「PHP」观察者模式模式

    引言   所属:行为型模式,常用设计模式之一       学习资料: <大话设计模式>程杰 模式概述   观察者模式定义了一种一对多的依赖关系,让多个观察者对象监听某一个主题对象.这个主题 ...

  7. 20190118-利用Python实现Pig Latin游戏

    1.利用Python实现Pig Latin字母游戏 “Pig Latin”是一个英语儿童文字改写游戏,整个游戏遵从下述规则:a. 元音字母是‘a’.‘e’.‘i’.‘o’.‘u’.字母‘y’在不是第一 ...

  8. BugkuWEB矛盾

    题目的意思是GET方式,num不能为数字,但是他的值为1,is_numeric(data)函数是判断data是不是数字返回bool类型 GET方式和POST方式区别 HTTP 定义了与服务器交互的不同 ...

  9. 插入排序,C语言实现

    插入排序是稳定排序,时间复杂度最低为O(n),最高为O(n^2),平均为O(n^2). 插入排序是将数组分为两部分,一部分已经排好序,另一部分未排好序,每次从未排好序的部分取第一个元素插入到已经排好序 ...

  10. VIM 键

    输入 vimtutor命令,可以打开Linux使用手册(基本使用). ***. 插入键: A: 行尾插入 a: 字符后面插入 i: 字符前面插入 I: 行首插入 r:只替换一次字符  R:一直替换,直 ...