题解

11 条题解

  • 3
    @ 2016-04-12 21:42:16

    用向量叉积来判断点是否在三角形内。然后就可以判定三角形是否在另一个三角形内。
    读入三角形后,按面积从小到大排序。
    维护一棵树,按照包含关系来分层,然后DFS计算面积。
    k=0时特判。

    #include <cmath>
    #include <cstdio>
    #include <cstdlib>
    #include <vector>
    #include <algorithm>
    
    using namespace std;
    
    static int n, k;
    
    struct Vector {
        Vector() {}
        Vector(double _x, double _y) : x(_x), y(_y) {}
    
        double x, y;
    };  // struct Vector
    
    struct Triangle {
        Vector p1, p2, p3;
    };  // struct Triangle
    
    struct Node;
    
    struct Node {
        Triangle triangle;
        vector<Node *> child;
        int height;
    };  // struct Node
    
    #define EPSLION 0.000001
    
    inline bool float_same(const double a, const double b) {
        return fabs(a - b) < EPSLION;
    }
    
    inline Vector subtract(const Vector &a, const Vector &b) {
        return Vector(a.x - b.x, a.y - b.y);
    }
    
    inline double cross(const Vector &a, const Vector &b) {
        return a.x * b.y - b.x * a.y;
    }
    
    inline bool contain(const Triangle &t, const Vector &p) {
        Vector p1 = subtract(p, t.p1);
        Vector p2 = subtract(p, t.p2);
        Vector p3 = subtract(p, t.p3);
        double d1 = cross(p1, p2);
        double d2 = cross(p2, p3);
        double d3 = cross(p3, p1);
    
        return float_same(d1, 0.0) || float_same(d2, 0.0) || float_same(d3, 0.0) ||
               (d1 > 0 && d2 > 0 && d3 > 0) || (d1 < 0 && d2 < 0 && d3 < 0);
    }
    
    inline bool contain(const Triangle &t1, const Triangle &t2) {
        return contain(t1, t2.p1) && contain(t1, t2.p2) && contain(t1, t2.p3);
    }
    
    inline double size(const Triangle &t) {
        Vector p(0.0, 0.0);
        Vector p1 = subtract(p, t.p1);
        Vector p2 = subtract(p, t.p2);
        Vector p3 = subtract(p, t.p3);
        double d1 = cross(p1, p2);
        double d2 = cross(p2, p3);
        double d3 = cross(p3, p1);
    
        return fabs(d1 + d2 + d3) * 0.5;
    }
    
    static Node *insert(Node *h, Triangle &t) {
        if (!h) {
            Node *p = new Node;
            p->triangle = t;
    
            return p;
        }
    
        for (unsigned i = 0; i < h->child.size(); i++) {
            if (contain(h->child[i]->triangle, t)) {
                h->child[i] = insert(h->child[i], t);
                h->child[i]->height = h->height + 1;
    
                return h;
            }
        }
    
        h->child.push_back(insert(NULL, t));
        h->child[h->child.size() - 1]->height = h->height + 1;
        return h;
    }
    
    static Triangle tri[100];
    
    static void initailize() {
        scanf("%d%d", &n, &k);
    
        for (int i = 1; i <= n; i++) {
            scanf("%lf%lf%lf%lf%lf%lf", &tri[i].p1.x, &tri[i].p1.y, &tri[i].p2.x,
                  &tri[i].p2.y, &tri[i].p3.x, &tri[i].p3.y);
        }  // for
    }
    
    static double dfs(Node *h) {
        if (!h)
            return 0.0;
    
        if (h->height < k) {
            double sum = 0.0;
    
            for (unsigned i = 0; i < h->child.size(); i++) {
                sum += dfs(h->child[i]);
            }
    
            return sum;
        } else {
            double fix = 0.0;
    
            for (unsigned i = 0; i < h->child.size(); i++) {
                fix += size(h->child[i]->triangle);
            }
    
            return size(h->triangle) - fix;
        }
    }
    
    static bool cmp(const Triangle &a, const Triangle &b) {
        return size(a) > size(b);
    }
    
    int main() {
        initailize();
        sort(tri + 1, tri + n + 1, cmp);
    
        Triangle ground;
        ground.p1.x = -1000.0;
        ground.p1.y = -1000.0;
        ground.p2.x = 1000.0;
        ground.p2.y = -1000.0;
        ground.p3.x = -1000.0;
        ground.p3.y = 1000.0;
        Node *tree = NULL;
        tree = insert(tree, ground);
        tree->height = 0;
    
        for (int i = 1; i <= n; i++) {
            tree = insert(tree, tri[i]);
        }  // for
    
        double all;
    
        if (k == 0) {
            double fix = 0.0;
            for (unsigned i = 0; i < tree->child.size(); i++) {
                fix += size(tree->child[i]->triangle);
            }
    
            all = 10000.0 - fix;
        } else
            all = dfs(tree);
    
        printf("%.5lf", all / 10000.0);
    
        return 0;
    }  // function main
    
    
    • @ 2016-04-13 20:23:49

      写死我了,这代码狗日的难写,0不用特判233。

    • @ 2016-04-13 20:28:57

      我啥都没说,贼爷

  • 0
    @ 2009-10-18 18:27:00

    编译通过...

    ├ 测试数据 01:答案正确... 0ms

    ├ 测试数据 02:答案正确... 0ms

    ├ 测试数据 03:答案正确... 0ms

    ├ 测试数据 04:答案正确... 0ms

    ├ 测试数据 05:答案正确... 0ms

    ├ 测试数据 06:答案正确... 0ms

    ├ 测试数据 07:答案正确... 0ms

    ├ 测试数据 08:答案正确... 0ms

    ├ 测试数据 09:答案正确... 0ms

    ├ 测试数据 10:答案正确... 0ms

    ---|---|---|---|---|---|---|---|-

    Accepted 有效得分:100 有效耗时:0ms

    计算几何 嘿嘿

  • 0
    @ 2009-02-01 09:18:22

    问了大牛才知道要用到高中选修数学里的叉积判断,勉强做了下,程序不长,主要是计算几何的知识

  • 0
    @ 2008-07-17 20:45:10

    因为有箱子属于的关系,本来想着用树结构+最远路来处理...看来是想复杂了

    膜拜星芸神牛~~

  • 0
    @ 2007-07-26 00:34:42

    编译通过...

    ├ 测试数据 01:答案错误... ├ 标准行输出

     ├ 错误行输出

    ├ 测试数据 02:答案错误... ├ 标准行输出

     ├ 错误行输出

    ├ 测试数据 03:答案错误... ├ 标准行输出

     ├ 错误行输出

    ├ 测试数据 04:答案错误... ├ 标准行输出

     ├ 错误行输出

    ├ 测试数据 05:答案错误... ├ 标准行输出

     ├ 错误行输出

    ├ 测试数据 06:答案错误... ├ 标准行输出

     ├ 错误行输出

    ├ 测试数据 07:答案错误... ├ 标准行输出

     ├ 错误行输出

    ├ 测试数据 08:答案错误... ├ 标准行输出

     ├ 错误行输出

    ├ 测试数据 09:答案错误... ├ 标准行输出

     ├ 错误行输出

    ├ 测试数据 10:答案错误... ├ 标准行输出

     ├ 错误行输出

    ---|---|---|---|---|---|---|---|-

    Unaccepted 有效得分:0 有效耗时:0ms

    怎么我输出的都是FACER啊··!!?!?!?

    ___|\__|\__|\__|\__|\__|\__|\__|\__|\__|\__|\__|_

    同样的程序 我第二次交上去后 就AC了~

    `\`\`\`\`\`\`\`\`\`\`\`\``

  • 0
    @ 2007-06-29 17:25:09

    第8、9个点有什么需要注意的吗?

  • 0
    @ 2006-11-06 17:15:11

    判点的时候x1 y1写成x1 x2都能40....这个数据无奈啊

  • 0
    @ 2006-11-05 21:10:31

    大箱子的面积不是101*101吗?

  • 0
    @ 2006-11-05 14:46:48

    编译通过...

    ├ 测试数据 01:答案正确... 0ms

    ├ 测试数据 02:答案正确... 0ms

    ├ 测试数据 03:答案正确... 0ms

    ├ 测试数据 04:答案正确... 0ms

    ├ 测试数据 05:答案正确... 0ms

    ├ 测试数据 06:答案正确... 0ms

    ├ 测试数据 07:答案正确... 0ms

    ├ 测试数据 08:答案正确... 0ms

    ├ 测试数据 09:答案正确... 0ms

    ├ 测试数据 10:答案正确... 0ms

    郁闷。。考试的时候少了一条语句——0分

    叉积计算……

  • 0
    @ 2006-11-05 10:09:21

    感谢 maidou

    你的程序极具建筑美

    极易于小羊们的理解

    p.s我的几何就好弱

  • 0
    @ 2006-11-05 07:45:50

    用计算几何中叉积的方法

    判断点A是否在向量 DE EF FD 的同侧

    若是 则三角形ABC在DEF内。

  • 1

信息

ID
1288
难度
4
分类
计算几何 点击显示
标签
(无)
递交数
138
已通过
61
通过率
44%
被复制
3
上传者