【立体几何】Journey to Jupiter Gym - 101991J 立体几何模板

2023-10-18 10:10

本文主要是介绍【立体几何】Journey to Jupiter Gym - 101991J 立体几何模板,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

https://cn.vjudge.net/problem/Gym-101991J

题目很长,其实就是给你一个正三角形,并且告诉你它的中点在Z轴上以及法向量,边长和顶点A的坐标(自由度已定),让你求A,B,C到Z轴上一点H的距离。

 

题解:高考向量题,考虑正三角形ABC,我们把OB拆成OD加DB,OD=-OA/2,DB可以通过连立三个方程得到(它垂直于AO和法向量,他的长度为L/2)

坑:

我一开始拆的是OA+AB,公式太长不可解orz,

后来解方程的时候写错了orz

然后y写成xorz 

最后没考虑逆时针输出orz(这里要用叉积判一下,OA X OB 的方向要与法向量同)

 

#include<algorithm>
#include<iostream>
#include<stdlib.h>
#include<string.h>
#include<math.h>
#include<stdio.h>
#include<vector>
#include<queue>
#include<string>
#include<ctime>
#include<stack>
#include<map>
#include<set>
#include<list>
using namespace std;
#define rep(i,j,k) for(int i = (int)j;i <= (int)k;i ++)
#define per(i,j,k) for(int i = (int)j;i >= (int)k;i --)
#define debug(x) cerr<<#x<<" = "<<(x)<<endl
#define mmm(a,b) memset(a,b,sizeof(a))
#define pb push_back
//#define x first
//#define y second

typedef double  db;
typedef long long ll;
const int MAXN = 100010;;
const int maxn = MAXN;
struct V {db x, y,z;V() {}void sc() { scanf("%lf%lf", &x, &y); }V(db a, db b) : x(a), y(b) { }V operator+(V o) { return V(x + o.x, y + o.y); }V operator-(V o) { return V(x - o.x, y - o.y); }db L() { return sqrt(x * x + y * y); }V N() {db l = L();return V(x / l, y / l);}V rot(db th) { return V(x * cos(th) - y * sin(th), x * sin(th) + y * cos(th)); }V operator*(db z) { return V(x * z, y * z); }db operator*(V o) { return x * o.x + y * o.y; }db operator|(V o) { return x * o.y - o.x * y; }void pr() { printf("%lf %lf\n", x, y); }
} p[maxn];//三维几何函数库#define eps 1e-8
#define zero(x) (((x)>0?(x):-(x))<eps)
struct point3 { db x, y, z; };
struct line3 { point3 a, b; };
struct plane3 { point3 a, b, c; };//计算cross product U x V
point3 xmult(point3 u, point3 v) {point3 ret;ret.x = u.y*v.z - v.y*u.z;ret.y = u.z*v.x - u.x*v.z;ret.z = u.x*v.y - u.y*v.x;return ret;
}//计算dot product U . V
db dmult(point3 u, point3 v) {return u.x*v.x + u.y*v.y + u.z*v.z;
}//矢量差 U - V
point3 subt(point3 u, point3 v) {point3 ret;ret.x = u.x - v.x;ret.y = u.y - v.y;ret.z = u.z - v.z;return ret;
}
point3 addt(point3 u, point3 v) {point3 ret;ret.x = u.x + v.x;ret.y = u.y + v.y;ret.z = u.z + v.z;return ret;
}//取平面法向量
point3 pvec(plane3 s) {return xmult(subt(s.a, s.b), subt(s.b, s.c));
}
point3 pvec(point3 s1, point3 s2, point3 s3) {return xmult(subt(s1, s2), subt(s2, s3));
}//两点距离,单参数取向量大小
db distance(point3 p1, point3 p2) {return sqrt((p1.x - p2.x)*(p1.x - p2.x) + (p1.y - p2.y)*(p1.y - p2.y) + (p1.z - p2.z)*(p1.z - p2.z));
}//向量大小
db vlen(point3 p) {return sqrt(p.x*p.x + p.y*p.y + p.z*p.z);
}int main() {freopen("jupiter.in", "r", stdin);int t; cin >> t;while (t--) {point3 N, A;db l, h;scanf("%lf%lf%lf%lf%lf%lf%lf%lf", &N.x, &N.y, &N.z, &A.x, &A.y, &A.z, &l, &h);//scanf("%f%f%f%f%f%f%f%f", &N.x, &N.y, &N.z, &A.x, &A.y, &A.z, &l, &h);//cin >> N.x >> N.y >> N.z >> A.x >> A.y >> A.z >> l >> h;point3 H = { 0.,0.,-h };db La, Lb, Lc;db up = N.z*A.x - A.z*N.x;db under = N.y*A.x - A.y*N.x;db coy = -up / under;db cox =( N.z + N.y*coy)/(-N.x);cox = (A.z + A.y*coy) / (-A.x);db zz=l*l / 4.0/(coy*coy + cox*cox + 1.0) ;db z = l/sqrt(coy*coy + cox * cox + 1.0)/2.0;//db z = l / 2.0 / (coy + cox + 1.0);db x = cox * z;db y = coy * z;point3 b = { x,y,z };point3 c = { -x,-y,-z };point3 t = xmult(A, b);if (t.z*N.z > 0);else swap(b, c);point3 unA = { -A.x / 2.,-A.y / 2.,-A.z / 2. };point3 B = addt(unA, b);point3 C = addt(unA, c);La = distance(A, H);Lb = distance(B, H);Lc = distance(C, H);//if (N.z < 0)swap(Lb, Lc);printf("%.6lf %.6lf %.6lf\n", La,Lb,Lc);}//cin >> t;
}
/*
2
13 -18 1 7 5 -1 15 12
-12 -17 1 7 -5 -1 15 32
13 -18 1 7 5 -1 15 12
-12 -17 1 7 -5 -1 15 3
*/
View Code

 

 ps:第一次霸榜??

然后抄一个三维模板,

这个板子的话就厉害了 ,有了二维向量的一切操作。

这里的旋转操作,可以让向量V绕一个法向量n逆时针转theta度。

于是我们就只有两行代码了,

V3 B = N.rot(A, PI*2.0 / 3.0);
V3 C = N.rot(A, PI*4.0 / 3.0);
#include<algorithm>
#include<iostream>
#include<stdlib.h>
#include<string.h>
#include<math.h>
#include<stdio.h>
#include<vector>
#include<queue>
#include<string>
#include<ctime>
#include<stack>
#include<map>
#include<set>
#include<list>
using namespace std;
#define rep(i,j,k) for(int i = (int)j;i <= (int)k;i ++)
#define per(i,j,k) for(int i = (int)j;i >= (int)k;i --)
#define debug(x) cerr<<#x<<" = "<<(x)<<endl
#define mmm(a,b) memset(a,b,sizeof(a))
#define pb push_back
//#define x first
//#define y second

typedef double  db;
typedef long long ll;
const int MAXN = 100010;;
const int maxn = MAXN;
const double eps = 1e-8;
const double PI = acos(-1.0);
struct V3 {db x, y, z;V3() {}V3(db xx, db yy, db zz) :x(xx), y(yy), z(zz) {}void sc() {scanf("%lf%lf%lf", &x, &y, &z);}db L() { return sqrt(x*x + y * y + z * z); }V3 N() { db l = L(); return V3(x / l, y / l, z / l); }V3 operator+(V3 o) { return V3(x + o.x, y + o.y,z+o.z); }V3 operator-(V3 o) { return V3(x - o.x, y - o.y,z-o.z); }V3 operator*(db zz) { return V3(x * zz, y * zz,z*zz); }db operator*(V3 o) { return x * o.x + y * o.y+z*o.z; }V3 operator|(V3 o) { return V3(y*o.z-z*o.y,z*o.x-x*o.z,x * o.y - o.x * y); }
};
int sgn(db x) {if (fabs(x) < eps)return 0;else if (x > 0)return 1;else return -1;
}
struct L3 {V3 s, e;L3() {}L3(V3 ss, V3 ee) :s(ss), e(ee) {}V3 rot(V3 p, db arg) {if (sgn(((s - p) | (e - p)).L()) == 0)return p;V3 f1 = (e - s) | (p - s);V3 f2 = (e - s) | (f1);db len = ((s - p) | (e - p)).L() / (s - e).L(); f1 = f1.N()*len; f2 = f2.N() * len;V3 h = p + f2;V3 pp = h + f1;return h + ((p - h)*cos(arg)) + ((pp - h)*sin(arg));}};int main() {freopen("jupiter.in", "r", stdin);int t; cin >> t;while (t--) {V3 n, A;n.sc(); A.sc();db L, H;scanf("%lf%lf", &L, &H);L3 N = L3(V3(0, 0, 0), n);V3 base = V3(0, 0, -H);V3 B = N.rot(A, PI*2.0 / 3.0);V3 C = N.rot(A, PI*4.0 / 3.0);printf("%.6lf %.6lf %.6lf\n", (base - A).L(), (base - B).L(), (base - C).L());}//cin >>t;
}
/*
2
13 -18 1 7 5 -1 15 12
-12 -17 1 7 -5 -1 15 32
13 -18 1 7 5 -1 15 12
-12 -17 1 7 -5 -1 15 3
*/

 

转载于:https://www.cnblogs.com/SuuT/p/10013288.html

这篇关于【立体几何】Journey to Jupiter Gym - 101991J 立体几何模板的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/231890

相关文章

基于Java实现模板填充Word

《基于Java实现模板填充Word》这篇文章主要为大家详细介绍了如何用Java实现按产品经理提供的Word模板填充数据,并以word或pdf形式导出,有需要的小伙伴可以参考一下... Java实现按模板填充wor编程d本文讲解的需求是:我们需要把数据库中的某些数据按照 产品经理提供的 word模板,把数据

poj3468(线段树成段更新模板题)

题意:包括两个操作:1、将[a.b]上的数字加上v;2、查询区间[a,b]上的和 下面的介绍是下解题思路: 首先介绍  lazy-tag思想:用一个变量记录每一个线段树节点的变化值,当这部分线段的一致性被破坏我们就将这个变化值传递给子区间,大大增加了线段树的效率。 比如现在需要对[a,b]区间值进行加c操作,那么就从根节点[1,n]开始调用update函数进行操作,如果刚好执行到一个子节点,

C++11第三弹:lambda表达式 | 新的类功能 | 模板的可变参数

🌈个人主页: 南桥几晴秋 🌈C++专栏: 南桥谈C++ 🌈C语言专栏: C语言学习系列 🌈Linux学习专栏: 南桥谈Linux 🌈数据结构学习专栏: 数据结构杂谈 🌈数据库学习专栏: 南桥谈MySQL 🌈Qt学习专栏: 南桥谈Qt 🌈菜鸡代码练习: 练习随想记录 🌈git学习: 南桥谈Git 🌈🌈🌈🌈🌈🌈🌈🌈🌈🌈🌈🌈🌈�

poj 1258 Agri-Net(最小生成树模板代码)

感觉用这题来当模板更适合。 题意就是给你邻接矩阵求最小生成树啦。~ prim代码:效率很高。172k...0ms。 #include<stdio.h>#include<algorithm>using namespace std;const int MaxN = 101;const int INF = 0x3f3f3f3f;int g[MaxN][MaxN];int n

uva 1342 欧拉定理(计算几何模板)

题意: 给几个点,把这几个点用直线连起来,求这些直线把平面分成了几个。 解析: 欧拉定理: 顶点数 + 面数 - 边数= 2。 代码: #include <iostream>#include <cstdio>#include <cstdlib>#include <algorithm>#include <cstring>#include <cmath>#inc

uva 11178 计算集合模板题

题意: 求三角形行三个角三等分点射线交出的内三角形坐标。 代码: #include <iostream>#include <cstdio>#include <cstdlib>#include <algorithm>#include <cstring>#include <cmath>#include <stack>#include <vector>#include <

poj 2104 and hdu 2665 划分树模板入门题

题意: 给一个数组n(1e5)个数,给一个范围(fr, to, k),求这个范围中第k大的数。 解析: 划分树入门。 bing神的模板。 坑爹的地方是把-l 看成了-1........ 一直re。 代码: poj 2104: #include <iostream>#include <cstdio>#include <cstdlib>#include <al

最大流、 最小费用最大流终极版模板

最大流  const int inf = 1000000000 ;const int maxn = 20000 , maxm = 500000 ;struct Edge{int v , f ,next ;Edge(){}Edge(int _v , int _f , int _next):v(_v) ,f(_f),next(_next){}};int sourse , mee

C++语法知识点合集:11.模板

文章目录 一、非类型模板参数1.非类型模板参数的基本形式2.指针作为非类型模板参数3.引用作为非类型模板参数4.非类型模板参数的限制和陷阱:5.几个问题 二、模板的特化1.概念2.函数模板特化3.类模板特化(1)全特化(2)偏特化(3)类模板特化应用示例 三、模板分离编译1.概念2.模板的分离编译 模版总结 一、非类型模板参数 模板参数分类类型形参与非类型形参 非类型模板

Smarty模板引擎工作机制(一)

深入浅出Smarty模板引擎工作机制,我们将对比使用smarty模板引擎和没使用smarty模板引擎的两种开发方式的区别,并动手开发一个自己的模板引擎,以便加深对smarty模板引擎工作机制的理解。 在没有使用Smarty模板引擎的情况下,我们都是将PHP程序和网页模板合在一起编辑的,好比下面的源代码: <?php$title="深处浅出之Smarty模板引擎工作机制";$content=