• [arc076e]connected?


    题意:

    给出一个$R imes C$的棋盘,其中$1$到$N$之间的每个正整数都会在棋盘上出现两次,第$i$个数出现的位置是$(X_{i,1},Y_{i,1})$和$(X_{i,2},Y_{i,2})$,现在目的是把每一对相同的数用线(粗细忽略不计)连起来,且线不能相交也不能越过棋盘边界,求是否能完成。

    $1leq R,Cleq 10^8$

    $1leq Nleq 10^5$

    题解:

    看上去是神仙题,实际上很假。。。

    大家有没有玩过麻将连连看那种小游戏?题意中的连线意义就差不多。首先如果把这个棋盘扩展到无限大,即没有棋盘边界的限制,显然一定能满足条件。因为棋盘边上的数字连的线肯定可以在向外连足够远之后连回来,而内部的线由于可以跨越每个格子的边界,必定可以满足条件。(正确性感性理解一下?)

    那么有了边界限制之后,就只用考虑在两个位置都在边界上的那些数字,把这些数字看成一对括号,如果整个边界上按顺序(顺时针或逆时针)能构成一个合法括号序列,那么就能满足,否则就不行。画个图感受一下:

     

     

     

     

     

    如图,左图是非法的而右图是合法的。那这个东西直接用栈判断一下就好了。。。先把所有位置排序,然后如果现在位置的数字和栈顶相等则弹出栈顶,否则把当前数字压入栈,最后判断栈是否为空即可。

    ps:这题细节极其恶心!写挂了五六次才过样例。。。(可能是我写法比较挫)

    代码:

     1 #include<algorithm>
     2 #include<iostream>
     3 #include<cstring>
     4 #include<cstdio>
     5 #include<cmath>
     6 #include<queue>
     7 #include<stack>
     8 #define inf 2147483647
     9 #define eps 1e-9
    10 using namespace std;
    11 typedef long long ll;
    12 struct node{
    13     int x,id;
    14 }li[4][100001];
    15 int r,c,n,x,y,xx,yy,nw,tot[4];
    16 stack<int>st;
    17 bool cmp1(node a,node b){
    18     return a.x<b.x;
    19 }
    20 bool cmp2(node a,node b){
    21     return a.x>b.x;
    22 }
    23 int main(){
    24     scanf("%d%d%d",&r,&c,&n);
    25     for(int i=1;i<=n;i++){
    26         scanf("%d%d%d%d",&x,&y,&xx,&yy);
    27         if((x&&y&&x!=r&&y!=c)||(xx&&yy&&xx!=r&&yy!=c))continue;
    28         if(!x)nw=3;
    29         else if(x==r)nw=1;
    30         else if(!y)nw=0;
    31         else if(y==c)nw=2;
    32         if(nw==1||nw==3)li[nw][++tot[nw]]=(node){y,i};
    33         else li[nw][++tot[nw]]=(node){x,i};
    34         if(!xx)nw=3;
    35         else if(xx==r)nw=1;
    36         else if(!yy)nw=0;
    37         else if(yy==c)nw=2;
    38         if(nw==1||nw==3)li[nw][++tot[nw]]=(node){yy,i};
    39         else li[nw][++tot[nw]]=(node){xx,i};
    40     }
    41     for(int i=0;i<4;i++){
    42         if(i==0||i==1)sort(li[i]+1,li[i]+tot[i]+1,cmp1);
    43         else sort(li[i]+1,li[i]+tot[i]+1,cmp2);
    44         for(int j=1;j<=tot[i];j++){
    45             if(!st.empty()&&li[i][j].id==st.top())st.pop();
    46             else st.push(li[i][j].id);
    47         }
    48     }
    49     if(st.empty())puts("YES");
    50     else puts("NO");
    51     return 0;
    52 }
  • 相关阅读:
    在WM中画个带有边框的Panel
    在PPC上安装SQL Mobile库
    利用SQL语句清理日志
    Asp.net Ajax 中的脚本错误: Sys未定义的解决方法
    python搭建简易服务器
    STL源码剖析读书笔记第3章
    mongodb 查找 排序 索引 命令
    STL源码剖析读书笔记第2章
    词排序
    关于淘宝直通车优化的一点感悟
  • 原文地址:https://www.cnblogs.com/dcdcbigbig/p/9815631.html
Copyright © 2020-2023  润新知