zoukankan      html  css  js  c++  java
  • poj1066

    题意:给出图中所有线段,和一个点,问这个点要出正方形至少穿越多少线。

    分析:所有线段端点都在正方形周边线上。走弯路是无意义的,不会使穿过的墙减少,因为线段都是接边界的,无法绕过。我们枚举周边线上的出口,连直线,看最少有几个交点。因为只有跨越端点的时候才会改变交点数量。所以我们只需在每两个端点间枚举一个点。

    View Code
    #include <iostream>
    #include
    <cstdlib>
    #include
    <cstring>
    #include
    <cstdio>
    #include
    <algorithm>
    #include
    <cmath>
    using namespace std;

    #define maxn 50
    #define zero(x) (((x)>0?(x):-(x))<eps)
    #define eps 1.0E-8

    struct Point
    {
    double x, y;
    Point()
    {
    }
    Point(
    double xx, double yy) :
    x(xx), y(yy)
    {
    }
    } point[maxn
    * 2], s;

    struct Line
    {
    Point a, b;
    Line()
    {
    }
    Line(Point aa, Point bb) :
    a(aa), b(bb)
    {
    }
    } line[maxn];

    int n, m, ans;

    bool operator <(const Point &a, const Point &b)
    {
    return atan2(a.y, a.x) < atan2(b.y, b.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);
    }

    int same_side(Point p1, Point p2, Line l)
    {
    return xmult(l.a, p1, l.b) * xmult(l.a, p2, l.b) > eps;
    }

    int dots_inline(Point p1, Line l)
    {
    return zero(xmult(p1, l.a, l.b));
    }

    int dot_online_in(Point p, Line l)
    {
    return zero(xmult(p, l.a, l.b)) && (l.a.x - p.x) * (l.b.x - p.x) < eps && (l.a.y - p.y) * (l.b.y - p.y) < eps;
    }

    int intersect_in(Line u, Line v)
    {
    if (!dots_inline(v.a, u) || !dots_inline(v.b, u))
    return !same_side(u.a, u.b, v) && !same_side(v.a, v.b, u);
    return dot_online_in(u.a, v) || dot_online_in(u.b, v) || dot_online_in(v.a, u) || dot_online_in(v.b, u);
    }

    int opposite_side(Point p1, Point p2, Line l)
    {
    return xmult(l.a, p1, l.b) * xmult(l.a, p2, l.b) < -eps;
    }

    int intersect_ex(Line u, Line v)
    {
    return opposite_side(u.a, u.b, v) && opposite_side(v.a, v.b, u);
    }

    void input()
    {
    scanf(
    "%d", &m);
    n
    = 0;
    for (int i = 0; i < m; i++)
    {
    scanf(
    "%lf%lf", &point[n].x, &point[n].y);
    point[n].x
    -= 50;
    point[n].y
    -= 50;
    n
    ++;
    scanf(
    "%lf%lf", &point[n].x, &point[n].y);
    point[n].x
    -= 50;
    point[n].y
    -= 50;
    n
    ++;
    line[i]
    = Line(point[i * 2], point[i * 2 + 1]);
    }
    point[n].x
    = -50;
    point[n
    ++].y = -50;
    point[n].x
    = 50;
    point[n
    ++].y = 50;
    point[n].x
    = 50;
    point[n
    ++].y = -50;
    point[n].x
    = -50;
    point[n
    ++].y = 50;
    scanf(
    "%lf%lf", &s.x, &s.y);
    s.x
    -= 50;
    s.y
    -= 50;
    }

    Point mid_point(Point
    &a, Point &b)
    {
    return Point((a.x + b.x) / 2, (a.y + b.y) / 2);
    }

    void work()
    {
    point[n]
    = point[0];
    ans
    = m;
    for (int i = 0; i < n; i++)
    {
    Line l(s, mid_point(point[i], point[i
    + 1]));
    int temp = 0;
    for (int i = 0; i < m; i++)
    if (intersect_in(l, line[i]))
    temp
    ++;
    ans
    = min(ans, temp);
    }
    }

    int main()
    {
    //freopen("t.txt", "r", stdin);
    input();
    sort(point, point
    + n);
    // for (int i = 0; i < n; i++)
    // printf("%f %f\n", point[i].x, point[i].y);
    work();
    printf(
    "Number of doors = %d\n", ans + 1);
    return 0;
    }
  • 相关阅读:
    ASP学习笔记
    Access restriction: The type 'BASE64Encoder'
    hdu2094:产生冠军(判断有环图)
    hdu1533:Going Home(KM匹配)
    hdu2112:HDU Today(最短路)
    hdu2112:HDU Today(最短路)
    hdu2813:One fihgt one(KM匹配)
    hdu2813:One fihgt one(KM匹配)
    hdu2236:无题II(枚举+匈牙利算法)
    hdu2236:无题II(枚举+匈牙利算法)
  • 原文地址:https://www.cnblogs.com/rainydays/p/2181250.html
Copyright © 2011-2022 走看看