Description

Recently in Farland, a country in Asia, a famous scientist Mr. Log Archeo has discovered ancient pyramids. But unlike those in Egypt and Central America, they have triangular (not rectangular) foundation. That is, they are tetrahedrons in mathematical sense. In order to find out some important facts about the early society of the country (it is widely believed that the pyramid sizes are in tight connection with Farland ancient calendar), Mr. Archeo needs to know the volume of the pyramids. Unluckily, he has reliable data about their edge lengths only. Please, help him!

Input

The file contains six positive integer numbers not exceeding 1000 separated by spaces, each number is one of the edge lengths of the pyramid ABCD. The order of the edges is the following: AB, AC, AD, BC, BD, CD.

Output

A real number -- the volume printed accurate to four digits after decimal point.
 
题目大意:给四面体的六条边,求这个四面体的体积。
思路:用欧拉四面体公式,注意每条边的对应关系。
 
代码(47MS):
 #include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <cmath>
using namespace std;
#define sqr(x) ((x) * (x)) typedef long long LL;
typedef long double LD; const int MAXN = ;
const double EPS = 1e-;
const double PI = acos(-1.0);//3.14159265358979323846
const double INF = ; inline int sgn(double x) {
return (x > EPS) - (x < -EPS);
} struct Point {
double x, y, ag;
Point() {}
Point(double x, double y): x(x), y(y) {}
void read() {
scanf("%lf%lf", &x, &y);
}
bool operator == (const Point &rhs) const {
return sgn(x - rhs.x) == && sgn(y - rhs.y) == ;
}
bool operator < (const Point &rhs) const {
if(y != rhs.y) return y < rhs.y;
return x < rhs.x;
}
Point operator + (const Point &rhs) const {
return Point(x + rhs.x, y + rhs.y);
}
Point operator - (const Point &rhs) const {
return Point(x - rhs.x, y - rhs.y);
}
Point operator * (const double &b) const {
return Point(x * b, y * b);
}
Point operator / (const double &b) const {
return Point(x / b, y / b);
}
double operator * (const Point &rhs) const {
return x * rhs.x + y * rhs.y;
}
double length() {
return sqrt(x * x + y * y);
}
double angle() {
return atan2(y, x);
}
Point unit() {
return *this / length();
}
void makeAg() {
ag = atan2(y, x);
}
void print() {
printf("%.10f %.10f\n", x, y);
}
};
typedef Point Vector; double dist(const Point &a, const Point &b) {
return (a - b).length();
} double cross(const Point &a, const Point &b) {
return a.x * b.y - a.y * b.x;
}
//ret >= 0 means turn right
double cross(const Point &sp, const Point &ed, const Point &op) {
return cross(sp - op, ed - op);
} double area(const Point& a, const Point &b, const Point &c) {
return fabs(cross(a - c, b - c)) / ;
}
//counter-clockwise
Point rotate(const Point &p, double angle, const Point &o = Point(, )) {
Point t = p - o;
double x = t.x * cos(angle) - t.y * sin(angle);
double y = t.y * cos(angle) + t.x * sin(angle);
return Point(x, y) + o;
} double cosIncludeAngle(const Point &a, const Point &b, const Point &o) {
Point p1 = a - o, p2 = b - o;
return (p1 * p2) / (p1.length() * p2.length());
} double includedAngle(const Point &a, const Point &b, const Point &o) {
return acos(cosIncludeAngle(a, b, o));
/*
double ret = abs((a - o).angle() - (b - o).angle());
if(sgn(ret - PI) > 0) ret = 2 * PI - ret;
return ret;
*/
} struct Seg {
Point st, ed;
double ag;
Seg() {}
Seg(Point st, Point ed): st(st), ed(ed) {}
void read() {
st.read(); ed.read();
}
void makeAg() {
ag = atan2(ed.y - st.y, ed.x - st.x);
}
};
typedef Seg Line; //ax + by + c > 0
Line buildLine(double a, double b, double c) {
if(sgn(a) == && sgn(b) == ) return Line(Point(sgn(c) > ? - : , INF), Point(, INF));
if(sgn(a) == ) return Line(Point(sgn(b), -c/b), Point(, -c/b));
if(sgn(b) == ) return Line(Point(-c/a, ), Point(-c/a, sgn(a)));
if(b < ) return Line(Point(, -c/b), Point(, -(a + c) / b));
else return Line(Point(, -(a + c) / b), Point(, -c/b));
} void moveRight(Line &v, double r) {
double dx = v.ed.x - v.st.x, dy = v.ed.y - v.st.y;
dx = dx / dist(v.st, v.ed) * r;
dy = dy / dist(v.st, v.ed) * r;
v.st.x += dy; v.ed.x += dy;
v.st.y -= dx; v.ed.y -= dx;
} bool isOnSeg(const Seg &s, const Point &p) {
return (p == s.st || p == s.ed) ||
(((p.x - s.st.x) * (p.x - s.ed.x) < ||
(p.y - s.st.y) * (p.y - s.ed.y) < ) &&
sgn(cross(s.ed, p, s.st)) == );
} bool isInSegRec(const Seg &s, const Point &p) {
return sgn(min(s.st.x, s.ed.x) - p.x) <= && sgn(p.x - max(s.st.x, s.ed.x)) <=
&& sgn(min(s.st.y, s.ed.y) - p.y) <= && sgn(p.y - max(s.st.y, s.ed.y)) <= ;
} bool isIntersected(const Point &s1, const Point &e1, const Point &s2, const Point &e2) {
return (max(s1.x, e1.x) >= min(s2.x, e2.x)) &&
(max(s2.x, e2.x) >= min(s1.x, e1.x)) &&
(max(s1.y, e1.y) >= min(s2.y, e2.y)) &&
(max(s2.y, e2.y) >= min(s1.y, e1.y)) &&
(cross(s2, e1, s1) * cross(e1, e2, s1) >= ) &&
(cross(s1, e2, s2) * cross(e2, e1, s2) >= );
} bool isIntersected(const Seg &a, const Seg &b) {
return isIntersected(a.st, a.ed, b.st, b.ed);
} bool isParallel(const Seg &a, const Seg &b) {
return sgn(cross(a.ed - a.st, b.ed - b.st)) == ;
} //return Ax + By + C =0 's A, B, C
void Coefficient(const Line &L, double &A, double &B, double &C) {
A = L.ed.y - L.st.y;
B = L.st.x - L.ed.x;
C = L.ed.x * L.st.y - L.st.x * L.ed.y;
}
//point of intersection
Point operator * (const Line &a, const Line &b) {
double A1, B1, C1;
double A2, B2, C2;
Coefficient(a, A1, B1, C1);
Coefficient(b, A2, B2, C2);
Point I;
I.x = - (B2 * C1 - B1 * C2) / (A1 * B2 - A2 * B1);
I.y = (A2 * C1 - A1 * C2) / (A1 * B2 - A2 * B1);
return I;
} bool isEqual(const Line &a, const Line &b) {
double A1, B1, C1;
double A2, B2, C2;
Coefficient(a, A1, B1, C1);
Coefficient(b, A2, B2, C2);
return sgn(A1 * B2 - A2 * B1) == && sgn(A1 * C2 - A2 * C1) == && sgn(B1 * C2 - B2 * C1) == ;
} double Point_to_Line(const Point &p, const Line &L) {
return fabs(cross(p, L.st, L.ed)/dist(L.st, L.ed));
} double Point_to_Seg(const Point &p, const Seg &L) {
if(sgn((L.ed - L.st) * (p - L.st)) < ) return dist(p, L.st);
if(sgn((L.st - L.ed) * (p - L.ed)) < ) return dist(p, L.ed);
return Point_to_Line(p, L);
} double Seg_to_Seg(const Seg &a, const Seg &b) {
double ans1 = min(Point_to_Seg(a.st, b), Point_to_Seg(a.ed, b));
double ans2 = min(Point_to_Seg(b.st, a), Point_to_Seg(b.ed, a));
return min(ans1, ans2);
} struct Circle {
Point c;
double r;
Circle() {}
Circle(Point c, double r): c(c), r(r) {}
void read() {
c.read();
scanf("%lf", &r);
}
double area() const {
return PI * r * r;
}
bool contain(const Circle &rhs) const {
return sgn(dist(c, rhs.c) + rhs.r - r) <= ;
}
bool contain(const Point &p) const {
return sgn(dist(c, p) - r) <= ;
}
bool intersect(const Circle &rhs) const {
return sgn(dist(c, rhs.c) - r - rhs.r) < ;
}
bool tangency(const Circle &rhs) const {
return sgn(dist(c, rhs.c) - r - rhs.r) == ;
}
Point pos(double angle) const {
Point p = Point(c.x + r, c.y);
return rotate(p, angle, c);
}
}; double CommonArea(const Circle &A, const Circle &B) {
double area = 0.0;
const Circle & M = (A.r > B.r) ? A : B;
const Circle & N = (A.r > B.r) ? B : A;
double D = dist(M.c, N.c);
if((D < M.r + N.r) && (D > M.r - N.r)) {
double cosM = (M.r * M.r + D * D - N.r * N.r) / (2.0 * M.r * D);
double cosN = (N.r * N.r + D * D - M.r * M.r) / (2.0 * N.r * D);
double alpha = * acos(cosM);
double beta = * acos(cosN);
double TM = 0.5 * M.r * M.r * (alpha - sin(alpha));
double TN = 0.5 * N.r * N.r * (beta - sin(beta));
area = TM + TN;
}
else if(D <= M.r - N.r) {
area = N.area();
}
return area;
} int intersection(const Seg &s, const Circle &cir, Point &p1, Point &p2) {
double angle = cosIncludeAngle(s.ed, cir.c, s.st);
//double angle1 = cos(includedAngle(s.ed, cir.c, s.st));
double B = dist(cir.c, s.st);
double a = , b = - * B * angle, c = sqr(B) - sqr(cir.r);
double delta = sqr(b) - * a * c;
if(sgn(delta) < ) return ;
if(sgn(delta) == ) delta = ;
double x1 = (-b - sqrt(delta)) / ( * a), x2 = (-b + sqrt(delta)) / ( * a);
Vector v = (s.ed - s.st).unit();
p1 = s.st + v * x1;
p2 = s.st + v * x2;
return + sgn(delta);
} double CommonArea(const Circle &cir, Point p1, Point p2) {
if(p1 == cir.c || p2 == cir.c) return ;
if(cir.contain(p1) && cir.contain(p2)) {
return area(cir.c, p1, p2);
} else if(!cir.contain(p1) && !cir.contain(p2)) {
Point q1, q2;
int t = intersection(Line(p1, p2), cir, q1, q2);
if(t == ) {
double angle = includedAngle(p1, p2, cir.c);
return 0.5 * sqr(cir.r) * angle;
} else {
double angle1 = includedAngle(p1, p2, cir.c);
double angle2 = includedAngle(q1, q2, cir.c);
if(isInSegRec(Seg(p1, p2), q1))return 0.5 * sqr(cir.r) * (angle1 - angle2 + sin(angle2));
else return 0.5 * sqr(cir.r) * angle1;
}
} else {
if(cir.contain(p2)) swap(p1, p2);
Point q1, q2;
intersection(Line(p1, p2), cir, q1, q2);
double angle = includedAngle(q2, p2, cir.c);
double a = area(cir.c, p1, q2);
double b = 0.5 * sqr(cir.r) * angle;
return a + b;
}
} struct Triangle {
Point p[];
Triangle() {}
Triangle(Point *t) {
for(int i = ; i < ; ++i) p[i] = t[i];
}
void read() {
for(int i = ; i < ; ++i) p[i].read();
}
double area() const {
return ::area(p[], p[], p[]);
}
Point& operator[] (int i) {
return p[i];
}
}; double CommonArea(Triangle tir, const Circle &cir) {
double ret = ;
ret += sgn(cross(tir[], cir.c, tir[])) * CommonArea(cir, tir[], tir[]);
ret += sgn(cross(tir[], cir.c, tir[])) * CommonArea(cir, tir[], tir[]);
ret += sgn(cross(tir[], cir.c, tir[])) * CommonArea(cir, tir[], tir[]);
return abs(ret);
} struct Poly {
int n;
Point p[MAXN];//p[n] = p[0]
void init(Point *pp, int nn) {
n = nn;
for(int i = ; i < n; ++i) p[i] = pp[i];
p[n] = p[];
}
double area() {
if(n < ) return ;
double s = p[].y * (p[n - ].x - p[].x);
for(int i = ; i < n; ++i)
s += p[i].y * (p[i - ].x - p[i + ].x);
return s / ;
}
};
//the convex hull is clockwise
void Graham_scan(Point *p, int n, int *stk, int &top) {//stk[0] = stk[top]
sort(p, p + n);
top = ;
stk[] = ; stk[] = ;
for(int i = ; i < n; ++i) {
while(top && cross(p[i], p[stk[top]], p[stk[top - ]]) <= ) --top;
stk[++top] = i;
}
int len = top;
stk[++top] = n - ;
for(int i = n - ; i >= ; --i) {
while(top != len && cross(p[i], p[stk[top]], p[stk[top - ]]) <= ) --top;
stk[++top] = i;
}
}
//use for half_planes_cross
bool cmpAg(const Line &a, const Line &b) {
if(sgn(a.ag - b.ag) == )
return sgn(cross(b.ed, a.st, b.st)) < ;
return a.ag < b.ag;
}
//clockwise, plane is on the right
bool half_planes_cross(Line *v, int vn, Poly &res, Line *deq) {
int i, n;
sort(v, v + vn, cmpAg);
for(i = n = ; i < vn; ++i) {
if(sgn(v[i].ag - v[i-].ag) == ) continue;
v[n++] = v[i];
}
int head = , tail = ;
deq[] = v[], deq[] = v[];
for(i = ; i < n; ++i) {
if(isParallel(deq[tail - ], deq[tail]) || isParallel(deq[head], deq[head + ]))
return false;
while(head < tail && sgn(cross(v[i].ed, deq[tail - ] * deq[tail], v[i].st)) > )
--tail;
while(head < tail && sgn(cross(v[i].ed, deq[head] * deq[head + ], v[i].st)) > )
++head;
deq[++tail] = v[i];
}
while(head < tail && sgn(cross(deq[head].ed, deq[tail - ] * deq[tail], deq[head].st)) > )
--tail;
while(head < tail && sgn(cross(deq[tail].ed, deq[head] * deq[head + ], deq[tail].st)) > )
++head;
if(tail <= head + ) return false;
res.n = ;
for(i = head; i < tail; ++i)
res.p[res.n++] = deq[i] * deq[i + ];
res.p[res.n++] = deq[head] * deq[tail];
res.n = unique(res.p, res.p + res.n) - res.p;
res.p[res.n] = res.p[];
return true;
} //ix and jx is the points whose distance is return, res.p[n - 1] = res.p[0], res must be clockwise
double dia_rotating_calipers(Poly &res, int &ix, int &jx) {
double dia = ;
int q = ;
for(int i = ; i < res.n - ; ++i) {
while(sgn(cross(res.p[i], res.p[q + ], res.p[i + ]) - cross(res.p[i], res.p[q], res.p[i + ])) > )
q = (q + ) % (res.n - );
if(sgn(dist(res.p[i], res.p[q]) - dia) > ) {
dia = dist(res.p[i], res.p[q]);
ix = i; jx = q;
}
if(sgn(dist(res.p[i + ], res.p[q]) - dia) > ) {
dia = dist(res.p[i + ], res.p[q]);
ix = i + ; jx = q;
}
}
return dia;
}
//a and b must be clockwise, find the minimum distance between two convex hull
double half_rotating_calipers(Poly &a, Poly &b) {
int sa = , sb = ;
for(int i = ; i < a.n; ++i) if(sgn(a.p[i].y - a.p[sa].y) < ) sa = i;
for(int i = ; i < b.n; ++i) if(sgn(b.p[i].y - b.p[sb].y) < ) sb = i;
double tmp, ans = dist(a.p[], b.p[]);
for(int i = ; i < a.n; ++i) {
while(sgn(tmp = cross(a.p[sa], a.p[sa + ], b.p[sb + ]) - cross(a.p[sa], a.p[sa + ], b.p[sb])) > )
sb = (sb + ) % (b.n - );
if(sgn(tmp) < ) ans = min(ans, Point_to_Seg(b.p[sb], Seg(a.p[sa], a.p[sa + ])));
else ans = min(ans, Seg_to_Seg(Seg(a.p[sa], a.p[sa + ]), Seg(b.p[sb], b.p[sb + ])));
sa = (sa + ) % (a.n - );
}
return ans;
} double rotating_calipers(Poly &a, Poly &b) {
return min(half_rotating_calipers(a, b), half_rotating_calipers(b, a));
}
//欧拉四面体公式AB, AC, AD, BC, BD, CD
double area(double p, double q, double r, double n, double m, double l) {
p *= p, q *= q, r *= r, n *= n, m *= m, l *= l;
long double ret = ;
ret += LD(p) * q * r;
ret += LD(p + q - n) * (q + r - l) * (p + r - m) / ;
ret -= LD(p + r - m) * q * (p + r - m) / ;
ret -= LD(p + q - n) * (p + q - n) * r / ;
ret -= LD(q + r - l) * (q + r - l) * p / ;
return sqrt(ret / );
} /*******************************************************************************************/ Point p[MAXN];
Circle cir;
double r;
int n; int main() {
double p, q, r, n, m, l;
while(cin>>p>>q>>r>>n>>m>>l) {
printf("%.4f\n", area(p, q, r, n, m, l));
}
}

POJ 2208 Pyramids(求四面体体积)的更多相关文章

  1. POJ 2208 Pyramids 欧拉四面体

    给出边长,直接就可以求出体积咯 关于欧拉四面体公式的推导及证明过程 2010-08-16 14:18 1,建议x,y,z直角坐标系.设A.B.C少拿点的坐标分别为(a1,b1,c1),(a2,b2,c ...

  2. POJ 2208--Pyramids(欧拉四面体体积计算)

    Pyramids Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 3451   Accepted: 1123   Specia ...

  3. POJ 3978 Primes(求范围素数个数)

    POJ 3978 Primes(求范围素数个数) id=3978">http://poj.org/problem? id=3978 题意: 给你一个区间范围A和B,要你求出[A,B]内 ...

  4. HDU 3642 Get The Treasury ( 线段树 求长方体体积并 )

    求覆盖三次及其以上的长方体体积并. 这题跟 http://wenku.baidu.com/view/d6f309eb81c758f5f61f6722.html 这里讲的长方体体积并并不一样. 因为本题 ...

  5. POJ 2208 已知边四面体六个长度,计算体积

    Pyramids Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 2718   Accepted: 886   Special ...

  6. POJ2208 Pyramids 四面体体积

    POJ2208给定四面体六条棱(有序)的长度 求体积 显然用高中立体几何的方法就可以解决. 给出代码 #include<iostream> #include<cstdio> # ...

  7. poj 3348--Cows(凸包求面积)

    链接:http://poj.org/problem?id=3348 Cows Time Limit: 2000MS   Memory Limit: 65536K Total Submissions:  ...

  8. POJ 1269 (直线求交)

    Problem Intersecting Lines (POJ 1269) 题目大意 给定两条直线,问两条直线是否重合,是否平行,或求出交点. 解题分析 主要用叉积做,可以避免斜率被0除的情况. 求交 ...

  9. poj 2449(A*求第K短路)

    题目链接:http://poj.org/problem?id=2449 思路:我们可以定义g[x]为源点到当前点的距离,h[x]为当前点到目标节点的最短距离,显然有h[x]<=h*[x](h*[ ...

随机推荐

  1. C++切勿混用带符号类型和无符号类型

    如果表达式里既有带符号类型又有无符号类型,当带符号类型取值为负时会出现异常结果. 因为带符号数会自动转化为无符号数. 例如 a*b,a=-1, b=1,a是int,b是unsigned int,如果在 ...

  2. ABAP术语-SAP GUI for HTML

    SAP GUI for HTML 原文:http://www.cnblogs.com/qiangsheng/archive/2008/03/14/1104996.html An ITS impleme ...

  3. vi模式下的编辑、删除、保存和退出

    vi + 文件名:进入 vi 模式 编辑模式:shift+: 退出编辑模式:Esc 退出编辑模式后可进行光标的上下左右移动(偶尔会出现ABCD,还不知道怎么解决,目前只能出来一个删除一个) 光标处:按 ...

  4. 动态链接库函数内的静态变量,奇妙的UNIQUE Bind

    title: 动态链接库函数内的静态变量,奇妙的UNIQUE Bind date: 2018-09-28 09:28:22 tags: --- 介绍 模板函数和内敛函数中的静态变量,在跨so中的表现, ...

  5. python学习笔记:第21天 常用内置模块之collections和time

    目录 一.collections模块 二.时间模块 也可以在我的个人博客上阅读 一.collections模块 1. Counter Counter是⼀个计数器,主要⽤统计字符的数量,之前如果我们要统 ...

  6. python函数的四种参数传递方式

    python中函数传递参数有四种形式 fun1(a,b,c) fun2(a=1,b=2,c=3) fun3(*args) fun4(**kargs) 四种中最常见是前两种,基本上一般点的教程都会涉及, ...

  7. Quartus II 项目文件分类及内容

  8. Java:内存泄露和内存溢出

    1. 内存溢出 (Memory Overflow) 是指程序在申请内存时,没有足够的内存空间供其使用,出现out of memory:比如申请了一个integer,但给它存了long才能存下的数,那就 ...

  9. SpspringBoot日志logback-spring.xml分环境

    SpspringBoot日志logback-spring.xml分环境 2017年08月02日 03:05:13 cqqianyi1 阅读数:30563 标签: logback slf4j sprin ...

  10. imageNamed和imageWithContextOfFile的区别?哪个性能高

    imageNamed性能高 1.用imageNamed的方式加载时,图片使用完毕后缓存到内存中,内存消耗多,加载速度快.即使生成的对象被 autoReleasePool释放了,这份缓存也不释放,如果图 ...