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 }