题目描述
Snuke is playing a puzzle game. In this game, you are given a rectangular board of dimensions R×C, filled with numbers. Each integer i from 1 through N is written twice, at the coordinates (xi,1,yi,1) and (xi,2,yi,2).
The objective is to draw a curve connecting the pair of points where the same integer is written, for every integer from 1 through N. Here, the curves may not go outside the board or cross each other.
Determine whether this is possible.
Constraints
1≤R,C≤108
1≤N≤105
0≤xi,1,xi,2≤R(1≤i≤N)
0≤yi,1,yi,2≤C(1≤i≤N)
All given points are distinct.
All input values are integers.
输入
Input is given from Standard Input in the following format:
R C N
x1,1 y1,1 x1,2 y1,2
:
xN,1 yN,1 xN,2 yN,2
输出
Print YES if the objective is achievable; print NO otherwise.
样例输入
4 2 3 0 1 3 1 1 1 4 1 2 0 2 2
样例输出
YES
提示
The above figure shows a possible solution.
来源/分类
题意:给出 2n 个点,两两对应的点,问 他们是否 不会出现线段交叉的现象。
分析:显然某个点两边都在矩阵边缘上才要考虑,那么将这类点找出来,按矩阵边缘顺时针排序,然后遍历,和栈顶数字相同就出栈,没出现过的就压进栈,最后判断栈是否为空即可,栈不空说明有线相交了。
AC代码:
/* Lyl */
#include <bits/stdc++.h>
#define inf 0x3f3f3f3f
#define pi acos(-1.0)
#define ms(a,b) memset(a,b,sizeof(a))
using namespace std;
typedef long long ll;
const int maxn = 2e5+5;
int R, C, n, que[maxn];
pair<int, int> par[maxn];
int judge(int a, int b)
{
return (a==0 || a==R || b==0 || b==C);
}
int dis(int a, int b)
{
if(a==0) return b;
if(b==C) return C + a;
if(a==R) return C + R + C - b;
return C + C + R + R - a;
}
int main()
{
int a, b, c, d, cnt=0, it=0;
scanf("%d%d%d", &R, &C, &n);
while(n--)
{
scanf("%d%d%d%d",&a, &b, &c, &d);
if(judge(a, b) && judge(c, d))
{
par[cnt++] = make_pair(dis(a, b), it);
par[cnt++] = make_pair(dis(c, d), it++);
}
}int num = 0;
sort(par, par+cnt);
for(int i=0; i<cnt; i++)
{
if(!num) que[++num] = par[i].second;
else if(par[i].second == que[num]) num--;
else que[++num] = par[i].second;
}
if(!num) puts("YES");
else puts("NO");
return 0;
}