【LOJ】#2070. 「SDOI2016」平凡的骰子
题解
用了一堆迷之复杂的结论结果迷之好写的计算几何????
好吧,要写立体几何了
如果有名词不懂自己搜吧
首先我们求重心,我们可以求带权重心,也就是x坐标的话是所有分割的小四面体的x坐标 * 四面体体积的和除以骰子的体积,y,z坐标同理
然后我们把这个骰子四面体剖分,剖分的话就是随便选在骰子内的一个点,对于骰子的每个面找相邻的三个点和这个点作为顶点组成的四面体
四面体的重心是四个点三维坐标和除以4
四面体的体积是三维混合积的绝对值除以6
然后对于每个面,我们把它剖分成三角形,发现它们二面角的和就是左右相邻的两条边和重心组成的面二面角的和
求出两个面二面角的法向量(就是垂直于平面的直线,可以用三维叉积求出来),然后求两个法向量的夹角,可以求出余弦值然后用反函数
代码
#include <bits/stdc++.h>
#define enter putchar('\n')
#define space putchar(' ')
#define pii pair<int,int>
#define fi first
#define se second
#define mp make_pair
#define MAXN 1000005
#define mo 999999137
#define pb push_back
//#define ivorysi
using namespace std;
typedef long long int64;
typedef double db;
template<class T>
void read(T &res) {
res = 0;T f = 1;char c = getchar();
while(c < '0' || c > '9') {
if(c == '-') f = -1;
c = getchar();
}
while(c >= '0' && c <= '9') {
res = res * 10 + c - '0';
c = getchar();
}
res *= f;
}
template<class T>
void out(T x) {
if(x < 0) {x = -x;putchar('-');}
if(x >= 10) out(x / 10);
putchar('0' + x % 10);
}
const db PI = acos(-1.0);
struct Point {
db x,y,z;
Point(){}
Point(db _x,db _y,db _z) {x = _x;y = _y;z = _z;}
friend Point operator + (const Point &a,const Point &b) {return Point(a.x + b.x,a.y + b.y,a.z + b.z);}
friend Point operator - (const Point &a,const Point &b) {return Point(a.x - b.x,a.y - b.y,a.z - b.z);}
friend Point operator * (const Point &a,const db &d) {return Point(a.x * d,a.y * d,a.z * d);}
friend Point operator / (const Point &a,const db &d) {return Point(a.x / d,a.y / d,a.z / d);}
friend Point operator * (const Point &a,const Point &b) {return Point(a.y * b.z - a.z * b.y,-a.x * b.z + a.z * b.x,a.x * b.y - a.y * b.x);}
friend db dot(const Point &a,const Point &b) {return a.x * b.x + a.y * b.y + a.z * b.z;}
Point operator -= (const Point &b) {return *this = *this - b;}
Point operator += (const Point &b) {return *this = *this + b;}
Point operator /= (const db &d) {return *this = *this / d;}
Point operator *= (const db &d) {return *this = *this * d;}
db norm() {
return sqrt(x * x + y * y + z * z);
}
}P[55],G;
vector<Point> S[85];
int N,F;
Point GetG(Point p,Point a,Point b,Point c) {
return (p + a + b + c) / 4.0;
}
db GetV(Point p,Point a,Point b,Point c) {
a -= p;b -= p;c -= p;
db res = abs(dot(a,b * c));
res /= 6.0;
return res;
}
Point CalcG() {
Point t = Point(0.0,0.0,0.0);
db sv = 0.0;
for(int i = 1 ; i <= F ; ++i) {
int s = S[i].size();
for(int j = 0 ; j <= s - 1 ; ++j) {
Point tmp = GetG(P[1],S[i][j],S[i][(j + 1) % s],S[i][(j + 2) % s]);
db v = GetV(P[1],S[i][j],S[i][(j + 1) % s],S[i][(j + 2) % s]);
sv += v;t += tmp * v;
}
}
t /= sv;
return t;
}
db CalcTangle(Point p,Point x,Point y,Point z) {
x -= p;y -= p;z -= p;
return acos(dot(x * y,x * z) / (x * y).norm() / (x * z).norm());
}
void Init() {
read(N);read(F);
db x,y,z;
for(int i = 1 ; i <= N ; ++i) {
scanf("%lf%lf%lf",&x,&y,&z);
P[i] = Point(x,y,z);
}
int k,a;
for(int i = 1 ; i <= F ; ++i) {
read(k);
for(int j = 1 ; j <= k ; ++j) {
read(a);
S[i].pb(P[a]);
}
}
}
void Solve() {
Point G = CalcG();
for(int i = 1 ; i <= F ; ++i) {
int s = S[i].size();
db x = -(s - 2) * PI;
for(int j = 0 ; j < s ; ++j) {
x += CalcTangle(G,S[i][j],S[i][(j + 1) % s],S[i][(j - 1 + s) % s]);
}
printf("%.7lf\n",x / (4 * PI));
}
}
int main() {
#ifdef ivorysi
freopen("f1.in","r",stdin);
#endif
Init();
Solve();
return 0;
}
【LOJ】#2070. 「SDOI2016」平凡的骰子的更多相关文章
- [LOJ 2070] 「SDOI2016」平凡的骰子
[LOJ 2070] 「SDOI2016」平凡的骰子 [题目链接] 链接 [题解] 原题求的是球面面积 可以理解为首先求多面体重心,然后算球面多边形的面积 求重心需要将多面体进行四面体剖分,从而计算出 ...
- LOJ#2070. 「SDOI2016」平凡的骰子(计算几何)
题面 传送门 做一道题学一堆东西不管什么时候都是美好的体验呢-- 前置芝士 混合积 对于三个三维向量\(a,b,c\),定义它们的混合积为\((a\times b)\cdot c\),其中$\time ...
- Loj #2192. 「SHOI2014」概率充电器
Loj #2192. 「SHOI2014」概率充电器 题目描述 著名的电子产品品牌 SHOI 刚刚发布了引领世界潮流的下一代电子产品--概率充电器: 「采用全新纳米级加工技术,实现元件与导线能否通电完 ...
- Loj #3096. 「SNOI2019」数论
Loj #3096. 「SNOI2019」数论 题目描述 给出正整数 \(P, Q, T\),大小为 \(n\) 的整数集 \(A\) 和大小为 \(m\) 的整数集 \(B\),请你求出: \[ \ ...
- Loj #3093. 「BJOI2019」光线
Loj #3093. 「BJOI2019」光线 题目描述 当一束光打到一层玻璃上时,有一定比例的光会穿过这层玻璃,一定比例的光会被反射回去,剩下的光被玻璃吸收. 设对于任意 \(x\),有 \(x\t ...
- Loj #3089. 「BJOI2019」奥术神杖
Loj #3089. 「BJOI2019」奥术神杖 题目描述 Bezorath 大陆抵抗地灾军团入侵的战争进入了僵持的阶段,世世代代生活在 Bezorath 这片大陆的精灵们开始寻找远古时代诸神遗留的 ...
- Loj #2542. 「PKUWC2018」随机游走
Loj #2542. 「PKUWC2018」随机游走 题目描述 给定一棵 \(n\) 个结点的树,你从点 \(x\) 出发,每次等概率随机选择一条与所在点相邻的边走过去. 有 \(Q\) 次询问,每次 ...
- Loj #3059. 「HNOI2019」序列
Loj #3059. 「HNOI2019」序列 给定一个长度为 \(n\) 的序列 \(A_1, \ldots , A_n\),以及 \(m\) 个操作,每个操作将一个 \(A_i\) 修改为 \(k ...
- Loj #3056. 「HNOI2019」多边形
Loj #3056. 「HNOI2019」多边形 小 R 与小 W 在玩游戏. 他们有一个边数为 \(n\) 的凸多边形,其顶点沿逆时针方向标号依次为 \(1,2,3, \ldots , n\).最开 ...
随机推荐
- 贪心问题:区间覆盖 POJ 1328 Rader Installation
题目:http://poj.org/problem?id=1328 题意:给定海岛个数,雷达半径,输入各个海岛坐标,求能覆盖所有海岛的最少雷达数 题解: 1. 贪心的区间覆盖问题,尽量让每个雷达覆盖更 ...
- 如何在Windows系统下隐藏文件
隐藏后只有键入文件夹名称才可访问,如果忘记路径就找不到了 attrib +s +a +h +r e:\bak\tools 取消的方法: attrib -a -s -h -r e:\bak\tools
- Nginx模块Lua-Nginx-Module学习笔记(二)Lua指令详解(Directives)
源码地址:https://github.com/Tinywan/Lua-Nginx-Redis Nginx与Lua编写脚本的基本构建块是指令. 指令用于指定何时运行用户Lua代码以及如何使用结果. 下 ...
- HBase基本概念
HBase是什么 HBase构建在 HDFS 之上的分布式列式键值存储系统.HBase内部管理的文件全部存储在HDFS中. HBase VS HDFS HDFS适合批处理场景 不支持数据随机查找 不适 ...
- 详解tomcat连接数和线程数
前言 在使用tomcat时,经常会遇到连接数.线程数之类的配置问题,要真正理解这些概念,必须先了解Tomcat的连接器(Connector). 在前面的文章 详解Tomcat配置文件server.xm ...
- WebService环境变量
将axis2部署到tomcat的webapps文件夹下: 因为该路径用于自动部署Web应用,将Web应用复制在该路径下,tomcat会将应用自动部署在容器中. AXIS_LIB:F:\tomcat\w ...
- [hadoop]hadoop api 新版本与旧版本的差别
突然现在对以后的职业方向有些迷茫,不知道去干什么,现在有一些语言基础,相对而言好的一些有Java和C,选来选去不知道该选择哪个方向,爬了好多网页后,觉得自己应该从java开始出发,之前有点心不在焉,不 ...
- Oracle错误: ORA-01722 无效数字
ORA-01722: 无效数字 主要原因是: 1.对于两个类型不匹配(一个数字类型,一个非数字类型,同下)的值进行赋值操作; 2.两个类型不匹配的值进行比较操作(例如,"="); ...
- jquery 根据后台传过来的值动态设置下拉框、单选框选中
更多内容推荐微信公众号,欢迎关注: jquery 根据后台传过来的值动态设置下拉框.单选框选中 $(function(){ var sex=$("#sex").val(); va ...
- UNIX环境高级编程 第1章 UNIX基础知识
所有操作系统都为运行在它之上的程序提供各种服务,典型的服务包括:执行新程序.打开文件.读写文件.分配存储空间.提供时间等. UNIX体系结构 严格来说,操作系统是一种软件,它控制计算机硬件资源,提供程 ...