HDU 5839 Special Tetrahedron (2016CCPC网络赛08) (暴力+剪枝)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5839

在一个三维坐标,给你n个点,问你有多少个四面体(4个点,6条边) 且满足至少四边相等 其余两边不相邻。

暴力4重循环,但是在第3重循环的时候需要判断是否是等腰三角形,这便是一个剪枝。在第4重循环的时候判断4点是否共面 (叉乘), 5或者6边相等就+1,4边相等就判断另外两边是否相交就行了。

赛后过的,觉得自己还是太菜了。

 1 //#pragma comment(linker, "/STACK:102400000, 102400000")8
 2 #include <algorithm>
 3 #include <iostream>
 4 #include <cstdlib>
 5 #include <cstring>
 6 #include <cstdio>
 7 #include <vector>
 8 #include <cmath>
 9 #include <ctime>
10 #include <list>
11 #include <set>
12 #include <map>
13 using namespace std;
14 typedef long long LL;
15 typedef pair <int, int> P;
16 const int N = 2e2 + 5;
17 int cost[N][N]; //两点的边长的平方
18 struct edge {
19     int x, y, z;
20 }a[N*N];
21 
22 int main()
23 {
24     int t;
25     scanf("%d", &t);
26     for(int ca = 1; ca <= t; ++ca) {
27         int n;
28         scanf("%d", &n);
29         for(int i = 1; i <= n; ++i) {
30             scanf("%d %d %d", &a[i].x, &a[i].y, &a[i].z);
31             for(int j = 1; j < i; ++j) {
32                 cost[i][j] = cost[j][i] = (a[i].x - a[j].x)*(a[i].x - a[j].x) + (a[i].y - a[j].y)*(a[i].y - a[j].y) + (a[i].z - a[j].z)*(a[i].z - a[j].z);
33             }
34         }
35         edge s1, s2, s3;
36         int ans, res = 0, x1, x2, y1, y2, len1, len2; //x1 y1是一个三角面不同边的两端 len1为等腰三角形的腰
37         for(int i1 = 1; i1 < n; ++i1) {
38             for(int i2 = i1 + 1; i2 < n; ++i2) {
39                 for(int i3 = i2 + 1; i3 < n; ++i3) {
40                     //判断3点是否形成等腰三角形
41                     if(cost[i1][i2] != cost[i1][i3] && cost[i2][i3] != cost[i1][i2] && cost[i2][i3] != cost[i1][i3])
42                         continue;
43                     else if(cost[i1][i2] == cost[i1][i3] && cost[i1][i2] == cost[i2][i3]) {
44                         len1 = cost[i1][i2], x1 = y1 = 0;
45                     }
46                     else if(cost[i1][i2] == cost[i2][i3]) {
47                         len1 = cost[i1][i2], x1 = i1, y1 = i3;
48                     }
49                     else if(cost[i1][i2] == cost[i1][i3]) {
50                         len1 = cost[i1][i2], x1 = i2, y1 = i3;
51                     }
52                     else {
53                         len1 = cost[i2][i3], x1 = i1, y1 = i2;
54                     }
55                     for(int i4 = i3 + 1; i4 <= n; ++i4) {
56                         if(cost[i1][i4] != cost[i2][i4] && cost[i1][i4] != cost[i3][i4] && cost[i3][i4] != cost[i2][i4])
57                             continue;
58                         else if(cost[i1][i4] == cost[i2][i4] && cost[i1][i4] == cost[i3][i4]) {
59                             len2 = cost[i1][i4], x2 = y2 = 0;
60                         }
61                         else if(cost[i1][i4] == cost[i2][i4]) {
62                             len2 = cost[i1][i4], x2 = i3, y2 = i4;
63                         }
64                         else if(cost[i1][i4] == cost[i3][i4]) {
65                             len2 = cost[i1][i4], x2 = i2, y2 = i4;
66                         }
67                         else {
68                             len2 = cost[i2][i4], x2 = i1, y2 = i4;
69                         }
70                         s1.x=a[i2].x-a[i1].x;s1.y=a[i2].y-a[i1].y;s1.z=a[i2].z-a[i1].z;  
71                         s2.x=a[i3].x-a[i1].x;s2.y=a[i3].y-a[i1].y;s2.z=a[i3].z-a[i1].z;  
72                         s3.x=a[i4].x-a[i1].x;s3.y=a[i4].y-a[i1].y;s3.z=a[i4].z-a[i1].z;  
73                         ans=s1.x*s2.y*s3.z+s1.y*s2.z*s3.x+s1.z*s2.x*s3.y-s1.z*s2.y*s3.x-s1.x*s2.z*s3.y-s1.y*s2.x*s3.z;  
74                         if(ans == 0) //4点是否共面
75                             continue;
76                         if(!x1 || !x2) { //6边或5边相等
77                             if(len1 == len2)
78                                 res++;
79                         }
80                         else {
81                             if(len1 == len2 && (x1 != x2 && x1 != y2 && y1 != x2 && y1 != y2)) //四边相等
82                                 res++;
83                         }
84                     }
85                 }
86             }
87         }
88         printf("Case #%d: %d\n", ca, res);
89     }
90     return 0;
91 }
View Code

 

posted @ 2016-08-15 00:55  Recoder  阅读(344)  评论(0编辑  收藏  举报