问题 F: Connected?

问题 F: Connected?

时间限制: 1 Sec  内存限制: 128 MB
提交: 38  解决: 20
[提交] [状态] [讨论版] [命题人:admin]

题目描述

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.

给你一个矩形,给你n对点,每一对点之间连线,求这些线互不相交的现象是否存在

思路

什么时候会相交呢,在两点都在矩形的边上的时候,这个画画图容易看出

那么怎么找呢,按照点在矩形上顺时针(或者逆时针)排下序,第一次出现的入栈,

第二次出现的判断是否为栈首的另一半,不是的话说明出现交叉了,

那么顺时针(或者逆时针)排下序的时候利用的就是这个点到原点(通过边缘的)的长度

代码源自这儿、

#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;
}

自己写一遍,顺便皮一下!~(-1)==1哦,cmp函数被我内置在结构体里了

#include <bits/stdc++.h>
using namespace std;
#define ll long long
struct Point
{
    int from,to;
    int flag;
    bool operator < (const Point a) const{
        return from<a.from;
    }
}P[200005];
int C,R,n;
int jude(int x,int y)
{
    if(!x)
        return y;
    if(y==C)
        return C+x;
    if(x==R)
        return C+R+C-y;
    if(!y)
        return C+C+R+R-x;
    return -1;
}

int main(){

    scanf("%d%d%d",&R,&C,&n);

    int cnt = 0;

    for(int i=0;i<n;i++)
    {
        int a,b,c,d;
        scanf("%d%d%d%d",&a,&b,&c,&d);

        int fl1 = jude(a,b);
        int fl2 = jude(c,d);

        if(!~fl1||!~fl2)///!~(-1)==0
            continue;
        if(fl1>fl2)swap(fl1,fl2);

        P[cnt].flag = 1;
        P[cnt].from = fl1;
        P[cnt].to = fl2;

        P[++cnt].flag = 2;
        P[cnt].from = fl2;
        P[cnt++].to = fl1;
    }
    stack<Point> Stk;

    sort(P,P+cnt);

    for(int i=0;i<cnt;i++)
    {
        if(P[i].flag==1)
            Stk.push(P[i]);
        else
            if(P[i].to==Stk.top().from)
                Stk.pop();
            else
            {
                printf("NO\n");
                return 0;
            }
    }
    printf("YES\n");
    return 0;
}

猜你喜欢

转载自blog.csdn.net/Du_Mingm/article/details/81412293