• uvalive 2797 Monster Trap


    题意:给定一些线段障碍,判断怪物能不能逃离到无穷远处。

    思路:从(0,0)点能否到无穷远处。用BFS搜索。那满足什么样的点符合要求,能加入到图中呢?

    遍历每个点,显然一开始已经在某些线段上的点要删去。再判断,两点之间的连线是否与其他线段有交。有则删去。

    这道题要注意如果两条线段重合,怎么办?延长每条线段,如果交点在线段内,不算。

      1 #include<cstdio>
      2 #include<cmath>
      3 #include<cstring>
      4 #include<algorithm>
      5 #include<iostream>
      6 #include<memory.h>
      7 #include<cstdlib>
      8 #include<vector>
      9 #define clc(a,b) memset(a,b,sizeof(a))
     10 #define LL long long int
     11 #define up(i,x,y) for(i=x;i<=y;i++)
     12 #define w(a) while(a)
     13 const double inf=0x3f3f3f3f;
     14 const int N = 4010;
     15 const double PI = acos(-1.0);
     16 using namespace std;
     17 const double eps = 1e-12;
     18 
     19 double dcmp(double x)
     20 {
     21     if(fabs(x) < eps) return 0;
     22     else return x < 0 ? -1 : 1;
     23 }
     24 
     25 struct Point
     26 {
     27     double x, y;
     28     Point(double x=0, double y=0):x(x),y(y) { }
     29 };
     30 
     31 typedef Point Vector;
     32 
     33 Vector operator + (const Point& A, const Point& B)
     34 {
     35     return Vector(A.x+B.x, A.y+B.y);
     36 }
     37 
     38 Vector operator - (const Point& A, const Point& B)
     39 {
     40     return Vector(A.x-B.x, A.y-B.y);
     41 }
     42 
     43 Vector operator * (const Point& A, double v)
     44 {
     45     return Vector(A.x*v, A.y*v);
     46 }
     47 
     48 Vector operator / (const Point& A, double v)
     49 {
     50     return Vector(A.x/v, A.y/v);
     51 }
     52 
     53 double Cross(const Vector& A, const Vector& B)
     54 {
     55     return A.x*B.y - A.y*B.x;
     56 }
     57 
     58 double Dot(const Vector& A, const Vector& B)
     59 {
     60     return A.x*B.x + A.y*B.y;
     61 }
     62 
     63 double Length(const Vector& A)
     64 {
     65     return sqrt(Dot(A,A));
     66 }
     67 
     68 bool operator < (const Point& p1, const Point& p2)
     69 {
     70     return p1.x < p2.x || (p1.x == p2.x && p1.y < p2.y);
     71 }
     72 
     73 bool operator == (const Point& p1, const Point& p2)
     74 {
     75     return p1.x == p2.x && p1.y == p2.y;
     76 }
     77 
     78 bool SegmentProperIntersection(const Point& a1, const Point& a2, const Point& b1, const Point& b2)
     79 {
     80     double c1 = Cross(a2-a1,b1-a1), c2 = Cross(a2-a1,b2-a1),
     81            c3 = Cross(b2-b1,a1-b1), c4=Cross(b2-b1,a2-b1);
     82     return dcmp(c1)*dcmp(c2)<0 && dcmp(c3)*dcmp(c4)<0;
     83 }
     84 
     85 bool OnSegment(const Point& p, const Point& a1, const Point& a2)
     86 {
     87     return dcmp(Cross(a1-p, a2-p)) == 0 && dcmp(Dot(a1-p, a2-p)) < 0;
     88 }
     89 
     90 const int maxv = 200 + 5;
     91 int V;
     92 int G[maxv][maxv], vis[maxv];
     93 
     94 bool dfs(int u)
     95 {
     96     if(u == 1) return true; // 1是终点
     97     vis[u] = 1;
     98     for(int v = 0; v < V; v++)
     99         if(G[u][v] && !vis[v] && dfs(v)) return true;
    100     return false;
    101 }
    102 
    103 const int maxn = 100 + 5;
    104 int n;
    105 Point p1[maxn], p2[maxn];
    106 
    107 // 在任何一条线段的中间(在端点不算)
    108 bool OnAnySegment(Point p)
    109 {
    110     for(int i = 0; i < n; i++)
    111         if(OnSegment(p, p1[i], p2[i])) return true;
    112     return false;
    113 }
    114 
    115 // 与任何一条线段规范相交
    116 bool IntersectWithAnySegment(Point a, Point b)
    117 {
    118     for(int i = 0; i < n; i++)
    119         if(SegmentProperIntersection(a, b, p1[i], p2[i])) return true;
    120     return false;
    121 }
    122 
    123 bool find_path()
    124 {
    125     // 构图
    126     vector<Point> vertices;
    127     vertices.push_back(Point(0, 0)); // 起点
    128     vertices.push_back(Point(1e5, 1e5)); // 终点
    129     for(int i = 0; i < n; i++)
    130     {
    131         if(!OnAnySegment(p1[i])) vertices.push_back(p1[i]);
    132         if(!OnAnySegment(p2[i])) vertices.push_back(p2[i]);
    133     }
    134     V = vertices.size();
    135     memset(G, 0, sizeof(G));
    136     memset(vis, 0, sizeof(vis));
    137     for(int i = 0; i < V; i++)
    138         for(int j = i+1; j < V; j++)
    139             if(!IntersectWithAnySegment(vertices[i], vertices[j]))
    140                 G[i][j] = G[j][i] = 1;
    141     return dfs(0);
    142 }
    143 
    144 int main()
    145 {
    146     while(cin >> n && n)
    147     {
    148         for(int i = 0; i < n; i++)
    149         {
    150             double x1, y1, x2, y2;
    151             cin >> x1 >> y1 >> x2 >> y2;
    152             Point a = Point(x1, y1);
    153             Point b = Point(x2, y2);
    154             Vector v = b - a;
    155             v = v / Length(v);
    156             p1[i] = a + v * 1e-6;
    157             p2[i] = b + v * 1e-6;
    158         }
    159         if(find_path()) cout << "no
    ";
    160         else cout << "yes
    ";
    161     }
    162     return 0;
    163 }
    View Code
  • 相关阅读:
    AI工程师职业规划和学习路线完整版
    Python基础面试题库
    Python运行的17个时新手常见错误小结
    一文总结学习 Python 的 14 张思维导图
    NLP大赛冠军总结:300万知乎多标签文本分类任务(附深度学习源码)
    超过 150 个最佳机器学习,NLP 和 Python教程
    任泽平:95页PPT分析2018(经济、房价、政策)
    为什么量化交易中稳定盈利是第一要义
    使用tushare获取股票实时分笔数据延时有多大
    5行代码实现1秒内获取一次所有股票的实时分笔数据
  • 原文地址:https://www.cnblogs.com/ITUPC/p/4893283.html
Copyright © 2020-2023  润新知