题面

传送门

做一道题学一堆东西不管什么时候都是美好的体验呢……

前置芝士

混合积

对于三个三维向量\(a,b,c\),定义它们的混合积为\((a\times b)\cdot c\),其中$\times \(表示叉乘,\)\cdot\(表示点乘,记为\)[a\ b\ c]$

关于它的几何意义的话……图片来自网络

其中\(Prj_{a\times b}c\)代表的是\(c\)这个向量在\(a\times b\)这个向量上的投影

那么显然我们最后得到的是以这三个向量为三条临边的一个六面体的体积

四面体体积

假设四面体的四个顶点分别为\(A,B,C,D\),并设三个向量\(a=B-A,b=C-A,c=D-A\),那么这个正四面体的体积就是\({1\over 6}[a\ b\ c]\)

这个应该比较显然吧……看上面那幅图,四面体的体积是以\(ab\)这个平行四边形为底,\(c\)为顶点的棱锥的一半,而棱锥的体积是棱柱的\({1\over 3}\),所以四面体体积就是六面体的\({1\over 6}\)了

凸多面体的重心

我们先来考虑一下凸多边形的重心好了……

对于三角形,它的重心就是它所有坐标的平均值

那么对于凸多边形,我们把它三角剖分了,记第\(i\)块的重心为\(a_i\),面积为\(m_i\),那么凸多边形的重心就是

\[{\sum_{i=1}^na_i\times m_i\over \sum_{i=1}^nm_i}
\]

那么凸多面体也差不多了,我们把它给四面体剖分了,然后也差不多按上面的算就好了

关于四面体剖分,具体的说我们在多面体中随便选一个点,比方说是\(p_1\),然后把每一个面给三角剖分,那么三角形就和选定的点构成了一个四面体。设\(v_i\)表示第\(i\)个四面体的体积,\(a_i\)表示重心,则最终多面体的重心为

\[{\sum_{i=1}^na_i\times v_i\over \sum_{i=1}^nv_i}
\]

二面角

这玩意儿班里数学课正在上然而我正在停课

简单来说就是两个平面的夹角

我们假设现在有\(a,b,c\)三个向量,要求\(ab\)这个平面和\(ac\)这个平面的二面角

那么求出\(ab\)和\(ac\)的法向量(法向量可以直接用叉积算),两个法向量之间的夹角就是二面角了,法向量之间的夹角直接用点积除以长度计算

可以画个图来理解。我们俯视的话,即要求二面角\(\angle 1\),那么显然两个法向量的夹角\(\angle 2=\angle 1\)

题解

总结起来的话……

三维计算几何。

需要混合积求四面体体积;

四面体剖分后合并带权重心求总重心;

四面体重心的横纵坐标是四个顶点的横纵坐标的平均数;

三维差积求平面的法向量;

点积求法向量夹角(二面角)

这些知识就可以了AC此题了。

时间复杂度\(O(nf)\)

顺便说一下数据范围是\(n,f\leq 100\),题面里错了

//minamoto
#include<bits/stdc++.h>
#define R register
#define inline __inline__ __attribute__((always_inline))
#define fp(i,a,b) for(R int i=(a),I=(b)+1;i<I;++i)
#define fd(i,a,b) for(R int i=(a),I=(b)-1;i>I;--i)
#define go(u) for(int i=head[u],v=e[i].v;i;i=e[i].nx,v=e[i].v)
using namespace std;
const int N=105;const double Pi=acos(-1.0);
struct node{
double x,y,z;
inline node(){}
inline node(R double xx,R double yy,R double zz):x(xx),y(yy),z(zz){}
inline node operator +(const node &b)const{return node(x+b.x,y+b.y,z+b.z);}
inline node operator -(const node &b)const{return node(x-b.x,y-b.y,z-b.z);}
inline node operator *(const node &b)const{return node(y*b.z-z*b.y,z*b.x-x*b.z,x*b.y-y*b.x);}
inline double operator ^(const node &b)const{return x*b.x+y*b.y+z*b.z;}
inline node operator *(const double &b)const{return node(x*b,y*b,z*b);}
inline node operator /(const double &b)const{return node(x/b,y/b,z/b);}
inline double norm(){return sqrt(x*x+y*y+z*z);}
}p[N],h[N*N],u,v;
int f[N][N],c[N];double sum,tmp;
int n,m;
inline double cross(const node &a,const node &b,const node &c){
node p=b*a,q=c*a;return acos((p^q)/p.norm()/q.norm());
}
int main(){
// freopen("testdata.in","r",stdin);
scanf("%d%d",&n,&m);
fp(i,1,n)scanf("%lf%lf%lf",&p[i].x,&p[i].y,&p[i].z);
fp(i,1,m){
scanf("%d",&c[i]);
fp(j,1,c[i])scanf("%d",&f[i][j]);
}
u=p[1],v=node(0,0,0),sum=0;
fp(i,1,m){
node u2=p[f[i][1]],v1,v2,t;
fp(j,2,c[i]-1){
v1=p[f[i][j]],v2=p[f[i][j+1]];
t=(u+u2+v1+v2)*0.25,tmp=fabs(((v1-u2)*(v2-u2))^(u-u2));
v=v+t*tmp,sum+=tmp;
}
}
tmp=1.0/sum,u=v*tmp,tmp=0.25/Pi;
fp(i,1,n)p[i]=p[i]-u;
fp(i,1,m){
sum=0;
fp(j,2,c[i]-1)sum+=cross(p[f[i][j]],p[f[i][j-1]],p[f[i][j+1]]);
sum+=cross(p[f[i][1]],p[f[i][c[i]]],p[f[i][2]]),
sum+=cross(p[f[i][c[i]]],p[f[i][c[i]-1]],p[f[i][1]]);
sum-=(c[i]-2)*Pi;
printf("%.7lf\n",sum*tmp);
}
return 0;
}

LOJ#2070. 「SDOI2016」平凡的骰子(计算几何)的更多相关文章

  1. [LOJ 2070] 「SDOI2016」平凡的骰子

    [LOJ 2070] 「SDOI2016」平凡的骰子 [题目链接] 链接 [题解] 原题求的是球面面积 可以理解为首先求多面体重心,然后算球面多边形的面积 求重心需要将多面体进行四面体剖分,从而计算出 ...

  2. 【LOJ】#2070. 「SDOI2016」平凡的骰子

    题解 用了一堆迷之复杂的结论结果迷之好写的计算几何???? 好吧,要写立体几何了 如果有名词不懂自己搜吧 首先我们求重心,我们可以求带权重心,也就是x坐标的话是所有分割的小四面体的x坐标 * 四面体体 ...

  3. LOJ#2082. 「JSOI2016」炸弹攻击 2(计算几何+双指针)

    题面 传送门 题解 我们枚举一下发射源,并把敌人和激光塔按极角排序,那么一组合法解就是两个极角之差不超过\(\pi\)且中间有敌人的三元组数,预处理一下前缀和然后用双指针就行了 //minamoto ...

  4. Loj #2192. 「SHOI2014」概率充电器

    Loj #2192. 「SHOI2014」概率充电器 题目描述 著名的电子产品品牌 SHOI 刚刚发布了引领世界潮流的下一代电子产品--概率充电器: 「采用全新纳米级加工技术,实现元件与导线能否通电完 ...

  5. Loj #3096. 「SNOI2019」数论

    Loj #3096. 「SNOI2019」数论 题目描述 给出正整数 \(P, Q, T\),大小为 \(n\) 的整数集 \(A\) 和大小为 \(m\) 的整数集 \(B\),请你求出: \[ \ ...

  6. Loj #3093. 「BJOI2019」光线

    Loj #3093. 「BJOI2019」光线 题目描述 当一束光打到一层玻璃上时,有一定比例的光会穿过这层玻璃,一定比例的光会被反射回去,剩下的光被玻璃吸收. 设对于任意 \(x\),有 \(x\t ...

  7. Loj #3089. 「BJOI2019」奥术神杖

    Loj #3089. 「BJOI2019」奥术神杖 题目描述 Bezorath 大陆抵抗地灾军团入侵的战争进入了僵持的阶段,世世代代生活在 Bezorath 这片大陆的精灵们开始寻找远古时代诸神遗留的 ...

  8. Loj #2542. 「PKUWC2018」随机游走

    Loj #2542. 「PKUWC2018」随机游走 题目描述 给定一棵 \(n\) 个结点的树,你从点 \(x\) 出发,每次等概率随机选择一条与所在点相邻的边走过去. 有 \(Q\) 次询问,每次 ...

  9. Loj #3059. 「HNOI2019」序列

    Loj #3059. 「HNOI2019」序列 给定一个长度为 \(n\) 的序列 \(A_1, \ldots , A_n\),以及 \(m\) 个操作,每个操作将一个 \(A_i\) 修改为 \(k ...

随机推荐

  1. oracle ROW_NUMBER用法

    Oracle中row_number().rank().dense_rank() 的区别 row_number的用途非常广泛,排序最好用它,它会为查询出来的每一行记录生成一个序号,依次排序且不会重复 使 ...

  2. FM模型

    [ 闲聊DNN CTR预估模型] http://www.mamicode.com/info-detail-1465813.html http://blog.csdn.net/bitcarmanlee/ ...

  3. Node.js中的express框架获取http参数

    最近本人在学习开发NodeJs,使用到express框架,对于网上的学习资料甚少,因此本人会经常在开发中做一些总结. express获取参数有三种方法:官网介绍如下 Checks route para ...

  4. 最全最详细的用JS过滤Emoji表情的输入

    在前端页面开发过程中,总会碰到不允许输入框输入emoji表情的需求,我的思路是通过编码用正则匹配表情,然后将其替换为空字符创.但是问题也是显而易见的,完整的编码集是什么呢?查阅了官方文档,发现上面并没 ...

  5. intellij idea运行Android程序时报错;Unable to locate adb within SDK

    环境:intellij idea15 问题:运行Android时报错Throwable:Unable to locate adb within SDK   解决方法:在SDK安装目录的\platfor ...

  6. NPOI工具类

    NPOI调用方法 DataTable dt = new DataTable(); Dictionary<string, string> header = new Dictionary< ...

  7. Cocoa Touch(五):网络请求 NSURLSession/AFNetworking, GCD, NSURLResquest

    NSURLRequest 网络请求的关键的就是NSURLRequest类,它的实例表示了请求报文实体以及请求的缓存策略等等,各种网络框架的最终目标都是把这个对象编译成为请求报文发送出去.下面用一个实例 ...

  8. thymeleaf 获取项目路径

    <p th:text=${salecode}></p> <a th:href="${#httpServletRequest.getScheme()+'://'+ ...

  9. Android工程目录结构

    ----------siwuxie095 首先创建一个简单的项目:MainActivity 工程目录结构一览: 工程目录结构介绍: 1.manifests目录 里面有一个AndroidManifest ...

  10. mysql查询赋值、修改拼接字符串

    sql中修改字符串类型的字段可以这么拼接:update tbName set UserName='abc'+UserName; 但mysql中就不行了,需要这样:update tbName set U ...