题目链接:https://arc076.contest.atcoder.jp/tasks/arc076_c
题目描述
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个点 但是 是1-1对应的n对点,问你他们是否都连接到自己另外一个点而且不会出现线段交叉的现象。
思路:想了半天考虑什么情况下会出现交叉现象,只有这条线段都在边缘的时候才会,只要不是2个都在边缘上,肯定可以用各种技巧让他们连接到一块,凑凑地方就行。所以只需要考虑哪些都在边缘的点,然后拍个序(顺时针 逆时针都行),用栈模拟下大的那个值出栈的位置关系即可。当前到右端点的时候一定是右端点在栈顶,否则肯定是出现了交叉。
#include<bits/stdc++.h>
using namespace std;
int R,C,N;
struct node{
int u;
int v;
int flag;
}no[200005];
bool cmp(node a,node b)
{
return a.u < b.u;
}
int Change(int x, int y)
{
if (x == 0)
return y;
else if (y == C)
return C + x;
else if (x == R)
return R + C + C - y;
else if (y == 0)
return R+R+C+C-x;
else
return -1;
}
int main()
{
int cnt=0;
scanf("%d%d%d",&R,&C,&N);
for(int i=0;i<N;i++)
{
int a,b,c,d;
scanf("%d%d%d%d",&a,&b,&c,&d);
int flag1=Change(a,b);
int flag2=Change(c,d);
if(flag1 == -1 || flag2 == -1)
continue;
if(flag1 > flag2)
swap(flag1,flag2);
no[cnt].flag=1;
no[cnt].u=flag1;
no[cnt++].v=flag2;
no[cnt].flag=2;
no[cnt].u=flag2;
no[cnt++].v=flag1;
}
stack<int>S;
sort(no,no+cnt,cmp);
for(int i=0;i<cnt;i++)
{
if(no[i].flag==1)
S.push(no[i].v);
else if(S.top()==no[i].u)
S.pop();
else
{
printf("NO\n");
return 0;
}
}
printf("YES\n");
return 0;
}