HDOJ 5839 计算几何+暴力

链接:

http://acm.hdu.edu.cn/showproblem.php?pid=5839

题意:

给你立体空间内的n个点,问能组成多少个四面体满足

1.至少四条棱相等

2.如果刚好四条棱相等,那么不相等的两条棱不能相邻

题解:

直接暴力,先枚举3个点,如果这三个点组成的三角形三边都不相等,那么就不用枚举第四个点了,其实很多情况都不用枚举第四个点

如果这个三角形是等边或等腰三角形,再分别枚举第四个点,分情况计算

开始的时候忘了判断还要判断四点共面,所以没用Point结构体,结果连样例都过不了,所以代码写的非常乱。。

代码:

 31 int n;
 32 double x[222], y[222], z[222];
 33 double dis[222][222];
 34 
 35 double sqr(double x) {
 36     return x*x;
 37 }
 38 
 39 double dist(int a, int b) {
 40     return sqrt(sqr(x[a] - x[b]) + sqr(y[a] - y[b]) + sqr(z[a] - z[b]));
 41 }
 42 
 43 struct Point {
 44     double x, y, z;
 45     Point(double x, double y, double z) :x(x), y(y), z(z) {}
 46 };
 47 
 48 Point operator -(const Point &a, const Point &b) {
 49     return Point(a.x - b.x, a.y - b.y, a.z - b.z);
 50 }
 51 
 52 Point det(Point a, Point b) {
 53     return Point(a.y*b.z - a.z*b.y, a.z*b.x - a.x*b.z, a.x*b.y - a.y*b.x);
 54 }
 55 
 56 double dot(Point a, Point b) {
 57     return a.x*b.x + a.y*b.y + a.z*b.z;
 58 }
 59 
 60 Point pvec(Point s1, Point s2, Point s3) {
 61     return det((s1 - s2), (s2 - s3));
 62 }
 63 
 64 bool zero(double x) {
 65     return fabs(x) < 1e-8;
 66 }
 67 
 68 bool check(int a, int b, int c, int d) {
 69     Point A(x[a], y[a], z[a]);
 70     Point B(x[b], y[b], z[b]);
 71     Point C(x[c], y[c], z[c]);
 72     Point D(x[d], y[d], z[d]);
 73     return zero(dot(pvec(A, B, C), D - A));
 74 }
 75 
 76 int main() {
 77     ios::sync_with_stdio(false), cin.tie(0);
 78     int T;
 79     cin >> T;
 80     rep(cas, 0, T) {
 81         cin >> n;
 82         rep(i, 0, n) cin >> x[i] >> y[i] >> z[i];
 83         rep(i, 0, n) rep(j, 0, n) dis[i][j] = dist(i, j);
 84         int ans = 0;
 85         rep(i, 0, n - 3) rep(j, i + 1, n - 2) rep(k, j + 1, n - 1) {
 86             double a = dis[i][j];
 87             double b = dis[j][k];
 88             double c = dis[k][i];
 89             if (a != b && b != c && c != a) continue;
 90             if (a == b && b == c) rep(h, k + 1, n) {
 91                 if (check(i, j, k, h)) continue;
 92                 double d = dis[h][i];
 93                 double e = dis[h][j];
 94                 double f = dis[h][k];
 95                 int sum = 0;
 96                 if (d != a) sum++;
 97                 if (e != a) sum++;
 98                 if (f != a) sum++;
 99                 if (sum <= 1) ans++;
100             }
101             else rep(h, k + 1, n) {
102                 if (check(i, j, k, h)) continue;
103                 double d = dis[h][i];
104                 double e = dis[h][j];
105                 double f = dis[h][k];
106                 int fg = 0;
107                 if (a == b) {
108                     if (d == a && f == a) fg = 1;
109                 }
110                 else if (b == c) {
111                     if (d == b && e == b) fg = 1;
112                 }
113                 else if (c == a) {
114                     if (e == c && f == c) fg = 1;
115                 }
116                 if (fg) ans++;
117             }
118         }
119         cout << "Case #" << cas + 1 << ": ";
120         cout << ans << endl;
121     }
122     return 0;
123 }

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值