zoukankan      html  css  js  c++  java
  • poj2462

    看八戒在做这个题,我也做了做。。

    坑很多,还是要注意细节。不得不吐槽,难道又到了计算几何只能套模板否则就一串WA的情况了么!

    要不是八戒做出来了,这题我估计我也就扔到这里了。。哥不服啊~所以得做出来!

    注意这个题,重复点、直线等关键词。还有,判断直线跟线段交点,需要先剪枝,就是判断这个线段端点跟直线端点叉乘是不是小于eps就行了。


    #include <iostream>
    #include <algorithm>
    #include <iomanip>
    #include <limits>

    using namespace std;

    #pragma warning(disable:4996)

    #define eps 1e-8
    #define zero(x) (((x)>0?(x):-(x))<eps)

    struct point{ double x, y; };
    struct line{ point a, b; };

    bool cmp(point p1, point p2)
    {
        if (fabs(p1.x - p2.x) < eps) return p1.y < p2.y;
        return p1.x < p2.x;
    }

    double xmult(point p1, point p2, point p0)
    {
        return (p1.x - p0.x)*(p2.y - p0.y) - (p2.x - p0.x)*(p1.y - p0.y);
    }

    point intersection(line u, line v)
    {
        point ret = u.a;
        double t = ((u.a.x - v.a.x)*(v.a.y - v.b.y) - (u.a.y - v.a.y)*(v.a.x - v.b.x)) / ((u.a.x - u.b.x)*(v.a.y - v.b.y) - (u.a.y - u.b.y)*(v.a.x - v.b.x));
        ret.x += (u.b.x - u.a.x)*t;
        ret.y += (u.b.y - u.a.y)*t;
        return ret;
    }

    double dist(point a, point b)
    {
        return sqrt((a.x - b.x) * (a.x - b.x) + (a.y - b.y) * (a.y - b.y));
    }

    int inside_polygon(point q, int n, point* p, int offset_x, int offset_y, int on_edge = 2)
    {
        point q2;
        int i = 0, count;
        while (i < n)
        for (count = i = 0, q2.x = rand() + offset_x, q2.y = rand() + offset_y; i < n; i++)
        if (zero(xmult(q, p[i], p[(i + 1) % n])) && (p[i].x - q.x)*(p[(i + 1) % n].x - q.x) < eps && (p[i].y - q.y)*(p[(i + 1) % n].y - q.y) < eps)
            return on_edge;
        else if (zero(xmult(q, q2, p[i])))
            break;
        else if (xmult(q, p[i], q2)*xmult(q, p[(i + 1) % n], q2) < -eps&&xmult(p[i], q, p[(i + 1) % n])*xmult(p[i], q2, p[(i + 1) % n]) < -eps)
            count++;
        return count & 1;
    }

    int main()
    {
        int num_of_point, num_of_line;
        while (cin >> num_of_point >> num_of_line && (num_of_point || num_of_line))
        {
            point p[1005];
            memset(p, 0sizeof(p));
            double Max_x = numeric_limits<double>::min(), Max_y = numeric_limits<double>::min();
            for (int i = 0; i < num_of_point; i++)
            {
                cin >> p[i].x >> p[i].y;
                if (p[i].x > Max_x) Max_x = p[i].x;
                if (p[i].y > Max_y) Max_y = p[i].y;
            }
            p[num_of_point] = p[0];//pay attention it has add for one, in reality, the size of it...i've made a mistake here
            for (int i = 0; i < num_of_line; i++)
            {
                line temp;
                cin >> temp.a.x >> temp.a.y >> temp.b.x >> temp.b.y;

                point intersects[1005];
                memset(intersects, 0sizeof(intersects));

                int count_of_intersects = 0;

                for (int i = 0; i < num_of_point; i++)
                {
                    if (xmult((p[i]), temp.a, temp.b)*xmult(p[i + 1], temp.a, temp.b) < eps)//can the sigment and the line intersect?
                    {
                        if (fabs(xmult((p[i]), temp.a, temp.b)) < eps&&fabs(xmult(p[i + 1], temp.a, temp.b)) < eps)//"same point"
                            continue;
                        line a = { p[i], p[i + 1] };
                        point inter = intersection(a, temp);
                        intersects[count_of_intersects++] = inter;
                    }
                }
                sort(intersects, intersects + count_of_intersects, cmp);
                double ans = 0;
                for (int i = 0; i < count_of_intersects - 1; i++)
                {
                    point center = { (intersects[i].x + intersects[i + 1].x) / 2, (intersects[i].y + intersects[i + 1].y) / 2 };
                    bool flag = inside_polygon(center, num_of_point + 1, p, (int)Max_x + 1, (int)Max_y + 1);
                    if (flag == 1 || flag == 2)
                        ans += dist(intersects[i], intersects[i + 1]);
                }
                cout << fixed << setprecision(3) << ans << endl;
            }
        }
        return 0;
    }



  • 相关阅读:
    php的rabbitmq扩展(未测试)
    rabbitmq安装
    windows操作系统安装jdk以及配置环境变量
    chrome设置user-agent
    pycharm中快捷键ctrl+c,ctrl+v,ctrl+f失效问题解决
    chrome设置user agent
    Pycharm鼠标滚动控制字体大小
    mouse事件实现可拖拽的div
    DOM事件委托
    !heap 手动查询内存泄漏
  • 原文地址:https://www.cnblogs.com/riskyer/p/3400206.html
Copyright © 2011-2022 走看看