ARC 076 E. Connected? - 结论

题目大意:
一个矩形,n个数字填入了其中(在格点上并且两两不同并且下标从1开始),每个数字出现两次。
对于一对相同的数字,使用一条极端细的可弯曲的线连起来(不允许出矩形)。
是否存在一种连线方案使得任意两条线不相交(有公共点都不行)。n<=1e5。
题解:显然只有那些连着边界的点对有用。然后给这个矩形的边界顺时针重新编号,然后就是不存在(a,b)和(c,d)使得a<c<b<d,也就是你从左上角顺时针走一圈应该得到的是一个回文串。

 
#include<bits/stdc++.h>
#define gc getchar()
#define rep(i,a,b) for(int i=a;i<=b;i++)
#define Rep(i,v) rep(i,0,(int)v.size()-1)
#define lint long long
#define db double
#define pb push_back
#define mp make_pair
#define fir first
#define sec second
#define debug(x) cerr<<#x<<"="<<x
#define sp <<" "
#define ln <<endl
using namespace std;
typedef pair<int,int> pii;
typedef set<int>::iterator sit;
const int N=100000;
inline int inn()
{
    int x,ch;while((ch=gc)<'0'||ch>'9');
    x=ch^'0';while((ch=gc)>='0'&&ch<='9')
        x=(x<<1)+(x<<3)+(ch^'0');return x;
}
struct P{
    int x,y,id,dis;
    inline int init() { return x=inn(),y=inn(); }
    inline int getdis(int r,int c)
    {
        if(x==0) return dis=y;
        if(y==c) return dis=c+x;
        if(x==r) return dis=c+r+(c-y);
        if(y==0) return dis=c+r+c+(r-x);
        return assert(0),0;
    }
    inline bool operator<(const P &p)const { return dis<p.dis; }
}p[N<<1];int s[N],vis[N];
#define on_bj(p) (p.x==0||p.x==r||p.y==0||p.y==c)
int main()
{
    int r=inn(),c=inn(),n=inn(),cnt=0;
    rep(i,1,n)
    {
        static P p1,p2;p1.init(),p2.init();
        if(!on_bj(p1)||!on_bj(p2)) continue;
        p[++cnt]=p1,p[cnt].id=i,p[++cnt]=p2,p[cnt].id=i;
    }
    rep(i,1,cnt) p[i].getdis(r,c);
    sort(p+1,p+cnt+1);int t=0;
    rep(i,1,cnt)
    {
        if(!vis[p[i].id]) vis[s[++t]=p[i].id]=1;
        else{
            if(s[t]!=p[i].id) return !printf("NO\n");
            vis[p[i].id]=0,t--;
        }
    }
    return !printf("YES\n");
}

猜你喜欢

转载自blog.csdn.net/Mys_C_K/article/details/83090618