hdu 5839(空间几何 网络选拔赛)
2016-08-15 11:06
218 查看
题意:
在三维空间给出若干个点,在这些点中选取四个点,组成四面体,满足这个四面体中至少有四条边是相等的。并且另两条不相等的边必须不相邻。
解题思路:
就是找出两条边,将这两条边作为四面体的对边。枚举第一条边找第二条边。找到一个平面经过第一条边的中点,且与第一条边垂直,第二条直线肯定在次平面内。所以枚举第一条直线的两个点,并且找到上述的平面,再遍历所有的点,找出在此平面上的点。在这些点中任意找两个点判断是否满足条件。满足条件的四面体分两种情况,一种是四条边相等,第二种是六条边相等。五条边相对的与四条边相等的情况一样。分这两种情况因为六条边相等的情况会被重复计算六次,四条边相等的被重复算两次。然后分开统计,之后出一下就是答案了。
(本来赛时是有思想的,结果实现的时候有一些情况忘记判断了,比如刚开始两条直线的重点重合也被统计了)
AC代码:
在三维空间给出若干个点,在这些点中选取四个点,组成四面体,满足这个四面体中至少有四条边是相等的。并且另两条不相等的边必须不相邻。
解题思路:
就是找出两条边,将这两条边作为四面体的对边。枚举第一条边找第二条边。找到一个平面经过第一条边的中点,且与第一条边垂直,第二条直线肯定在次平面内。所以枚举第一条直线的两个点,并且找到上述的平面,再遍历所有的点,找出在此平面上的点。在这些点中任意找两个点判断是否满足条件。满足条件的四面体分两种情况,一种是四条边相等,第二种是六条边相等。五条边相对的与四条边相等的情况一样。分这两种情况因为六条边相等的情况会被重复计算六次,四条边相等的被重复算两次。然后分开统计,之后出一下就是答案了。
(本来赛时是有思想的,结果实现的时候有一些情况忘记判断了,比如刚开始两条直线的重点重合也被统计了)
AC代码:
#include<iostream> #include<cstdio> #include<cstring> #include<cmath> #include<algorithm> #include<queue> #include<map> #include<vector> #define eps 1e-11 using namespace std; typedef long long ll; ll neq,eq; ll ans; int n; struct node { double x,y,z; }p[300]; bool cmp(node a,node b) { if(fabs(a.x-b.x)<=eps) { if(fabs(a.y-b.y)<=eps) return a.z<b.z; return a.y<b.y; } return a.x<b.x; } double juli(node a,node b)///两点之间的距离 { return (a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y)+(a.z-b.z)*(a.z-b.z); } void work(node a,node b){ int getin[300];/// int cnt=0;///统计在第一条边找到的平面上的点的个数 double dis1=juli(a,b); double dis2; node mid;///第一条边中点 mid.x=(a.x+b.x)/2; mid.y=(a.y+b.y)/2,mid.z=(a.z+b.z)/2; double k1,k2,k3,d; k1=a.x-b.x,k2=a.y-b.y,k3=a.z-b.z; d=k1*mid.x+k2*mid.y+k3*mid.z;///队友说这是法向量跟一个点确定一个平面 for(int i=0;i<n;i++) { if(fabs(k1*p[i].x+k2*p[i].y+k3*p[i].z-d)<=eps)///判断是否在平面上 getin[cnt++]=i;///在平面上的下标存储下来 } if(cnt<1) return ; node mid2;///满足条件的第二条边的中点 double m1,m2,m3; double l1,l2,l3; for(int i=0;i<cnt;i++) { for(int j=i+1;j<cnt;j++) { mid2.x=(p[getin[i]].x+p[getin[j]].x)/2; mid2.y=(p[getin[i]].y+p[getin[j]].y)/2; mid2.z=(p[getin[i]].z+p[getin[j]].z)/2; m1=mid2.x-mid.x;m2=mid2.y-mid.y;m3=mid2.z-mid.z; l1=p[getin[i]].x-p[getin[j]].x; l2=p[getin[i]].y-p[getin[j]].y; l3=p[getin[i]].z-p[getin[j]].z; if(fabs(m1*l1+m2*l2+m3*l3)<=eps) { if(fabs(m1)<eps&&fabs(m2)<eps&&fabs(m3)<eps) ///当找到的两条直线的中点重合不满足条件 { continue; } dis2=juli(p[getin[i]],p[getin[j]]); if(fabs((dis1-dis2))<=eps&&fabs(juli(a,p[getin[i]])-juli(a,b))<=eps) eq++;///六条边相等的情况 else neq++;///非六条边相等的情况 } } } } int main() { int cas=0; int T; scanf("%d",&T); while(T--) { ans=0; eq=0,neq=0; scanf("%d",&n); for(int i=0;i<n;i++) { scanf("%lf%lf%lf",&p[i].x,&p[i].y,&p[i].z); } sort(p,p+n,cmp);///排序下面的循环进行除重 int nn=1; for(int i=1;i<n;i++) { if((fabs(p[i].x-p[i-1].x)<=eps)&&(fabs(p[i].y-p[i-1].y)<=eps)&&(fabs(p[i].z-p[i-1].z)<=eps)) continue; else { p[nn].x=p[i].x; p[nn].y=p[i].y; p[nn].z=p[i].z; nn++; } } n=nn; if(n<4) { printf("Case #%d: 0\n",++cas); continue; } for(int i=0;i<n;i++) { for(int j=i+1;j<n;j++)///枚举第一条边的两个点 { work(p[i],p[j]); } } ans=eq/6+neq/2; printf("Case #%d: %I64d\n",++cas,ans); } return 0; }
相关文章推荐
- HDU 5839 Special Tetrahedron(计算几何)——2016中国大学生程序设计竞赛 - 网络选拔赛
- 2016中国大学生程序设计竞赛 - 网络选拔赛 hdu 5839 Special Tetrahedron
- 2017中国大学生程序设计竞赛 - 网络选拔赛 HDU 6154 CaoHaha's staff(几何找规律)
- HDU 4449 Building Design 第37届ACM/ICPC 金华赛区H题 (计算几何,三维凸包+空间坐标旋转+二维凸包)
- HDU 4741 Save Labman No.004 (2013杭州网络赛1004题,求三维空间异面直线的距离及最近点)
- HDU 5839 Special Tetrahedron 计算几何
- hdu 5839(三维几何)
- 浅谈关于空间几何的网络特征
- HDU 5833 Zhu and 772002 2016中国大学生程序设计竞赛 - 网络选拔赛(高斯消元)
- HDU 5832 A water problem(取模~)—— 2016中国大学生程序设计竞赛 - 网络选拔赛
- HDU 5839 Special Tetrahedron (三维计算几何)
- 2013杭州网络赛D题HDU 4741(计算几何 解三元一次方程组)
- hdu-5060(空间几何计算)
- HDU 4998 Rotate(计算几何)2014年鞍山赛区网络赛
- hdu 5839 三维几何 (暴力
- HDU 4741 Save Labman No.004 ( 三维计算几何 空间异面直线距离 )
- hdu 4766 Network 长春网络赛 1008 计算几何
- hdu 5476 Explore Track of Point 2015上海网络赛 几何
- HDU-5832 HDU-1212/2016网络选拔赛/大数取余
- hdu-5839 Special Tetrahedron(计算几何)