AtCoder Regular Contest 076 E Connected?[几何][数据结构优化]

传送门:http://arc076.contest.atcoder.jp/tasks/arc076_c

Sample Input 1

4 2 3
0 1 3 1
1 1 4 1
2 0 2 2

Sample Output 1

YES

题意:判断是否可以在图内连线使相同数字连接起来。

题解:作图可以发现只要不是两个点都位于矩形边界之上,都一定可以通过各种神奇的扭曲实现连接(总有缝可以钻:))。所以排除所有两点不同时在矩形边界的线段,剩下的只需要保证两点都在边界的线段不相交即可,然而正常判断线段相交方法需要N^2。自己做的时候只会排序后按斜率确定边界是否合法,但是需要判断两点在同一边的线段是否跨越当前线段,非常麻烦。官方题解用了栈处理,按顺时针排序所有线段后(线段两点也按顺时针方向排序),按顺时针遍历每个点,如果是线段起始点,push这个点对应的终止点。如果是线段终止点,检查栈顶是否是这个点,如果不是则当前点线段则和应该出现的点的线段一定相交,具体看代码。

右图遍历到A‘时栈顶应该为B‘,所以不成立。

 

代码:

 1 #define _CRT_SECURE_NO_DEPRECATE
 2 #pragma comment(linker, "/STACK:102400000,102400000")
 3 #include<iostream>  
 4 #include<cstdio>  
 5 #include<fstream>  
 6 #include<iomanip>
 7 #include<algorithm>  
 8 #include<cmath>  
 9 #include<deque>  
10 #include<vector>  
11 #include<assert.h>
12 #include<bitset>
13 #include<queue>  
14 #include<string>  
15 #include<cstring>  
16 #include<map>  
17 #include<stack>  
18 #include<set>
19 #include<functional>
20 #define pii pair<int, int>
21 #define mod 1000000007
22 #define mp make_pair
23 #define pi acos(-1)
24 #define eps 0.00000001
25 #define mst(a,i) memset(a,i,sizeof(a))
26 #define all(n) n.begin(),n.end()
27 #define lson(x) ((x<<1))  
28 #define rson(x) ((x<<1)|1) 
29 #define inf 0x3f3f3f3f
30 typedef long long ll;
31 typedef unsigned long long ull;
32 using namespace std;
33 int r, c;
34 class T {
35 public:
36     int mode, v, ope;
37     bool operator<(const T&a)
38     {
39         return v < a.v;
40     }
41 };
42 int getnum(int x, int y)
43 {
44     if (y == 0)
45         return x;
46     else if (x == 0)
47         return r + r + c + c - y;
48     else if (x == c)
49         return x + y;
50     else if (y == r)
51         return r + c + c - x;
52     else return -1;
53 }
54 
55 vector<T>a;
56 stack<int>sve;
57 int main()
58 {
59     ios::sync_with_stdio(false);
60     cin.tie(0);
61     int i, j, k, m, n;
62     int x1, x2, y1, y2;
63     cin >> r >> c >> n;
64     int tempa, tempb;
65     for (int i = 1; i <= n; ++i)
66     {
67         cin >> y1 >> x1 >> y2 >> x2;
68         tempa = getnum(x1, y1);
69         tempb = getnum(x2, y2);
70         if (tempb == -1 || tempa == -1)continue;
71         if (tempb < tempa)swap(tempa, tempb);
72         a.push_back({ 1,tempa,tempb });
73         a.push_back({ 2,tempb,tempa });
74     }
75     sort(all(a));
76     for (int i = 0; i < a.size(); ++i)
77     {
78         if (a[i].mode == 1)
79             sve.push(a[i].ope);
80         else if (sve.top() == a[i].v)
81                 sve.pop();
82         else
83         {
84             cout << "NO" << endl;
85             return 0;
86         }
87     }
88     cout << "YES" << endl;
89     return 0;
90 }

 

posted @ 2017-06-25 04:22  Meternal  阅读(538)  评论(0编辑  收藏  举报