upc - 6570: Connected? (思维)

题目描述

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.

来源/分类

ABC065&ARC076 

 

题意:给出 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;

}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值