• Codeforces Round #575 (Div. 3) E


    Codeforces Round #575 (Div. 3)

    E - Connected Component on a Chessboard

    You are given two integers b and w. You have a chessboard of size 109×109 with the top left cell at (1;1), the cell (1;1) is painted white.

    Your task is to find a connected component on this chessboard that contains exactly b black cells and exactly w white cells. Two cells are called connected if they share a side (i.e. for the cell (x,y) there are at most four connected cells: (x−1,y),(x+1,y),(x,y−1),(x,y+1)). A set of cells is called a connected component if for every pair of cells C1 and C2 from this set, there exists a sequence of cells c1, c2, ..., ck such that c1=C1, ck=C2, all ci from 1 to k are belong to this set of cells and for every i∈[1,k−1], cells ci and ci+1 are connected.

    Obviously, it can be impossible to find such component. In this case print "NO". Otherwise, print "YES" and any suitable connected component.

    You have to answer q independent queries.

    Input

    The first line of the input contains one integer q (1≤q≤105) — the number of queries. Then q queries follow.

    The only line of the query contains two integers b and w (1≤b,w≤105) — the number of black cells required and the number of white cells required.

    It is guaranteed that the sum of numbers of cells does not exceed 2⋅105 (∑w+∑b≤2⋅105).

    Output

    For each query, print the answer to it.

    If it is impossible to find the required component, print "NO" on the first line.

    Otherwise, print "YES" on the first line. In the next b+w lines print coordinates of cells of your component in any order. There should be exactly b black cells and w white cells in your answer. The printed component should be connected.

    If there are several answers, you can print any. All coordinates in the answer should be in the range [1;109].

    Example

    input

    3

    1 1

    1 4

    2 5

    output

    YES

    2 2

    1 2

    YES

    2 3

    1 3

    3 3

    2 2

    2 4

    YES

    2 3

    2 4

    2 5

    1 3

    1 5

    3 3

    3 5

     

    题意:题目意思是给你个黑白格子相邻的10^9 * 10^9 棋盘给你,(1,1)位置为白,然后相邻格子连接称为联通,

    给你一个黑色单元格数和白色单元格数,让你找出由这些格数组成的联通块,

    能找出输出 "YES" ,和每个格子坐标,找不到输出 "NO" 。

    思路:我们首先可以发现 坐标 (x,y)的点,(x+y)%2=1时为黑格,(x+y)%2=0时为白格。

    另外:联通块中 设黑格子数为 hei,白格子数为 bai ,有结论 

    当 黑格数少时,hei <= bai*3+1 ;当白格数少时 bai <= hei*3+1 。因为最大构成情况就是 几个十字型的形状连续组合在一起,

    其中十字中间格颜色跟相邻上下左右颜色肯定是不同的,(可以自己在纸上画一画思考下)。那么我们就可以根据这种形状来构造联通块,

    就是一直构造十字型的左半边(上中下左),当后面格子数剩余时可以用bfs解决。

    由于黑白格子数数量多少基本是同一个问题,只是中心构造起点不同,那我们可以用个交换函数归为一种情况,(写的有点复杂)

      1 #include<iostream>
      2 #include<cstdio>
      3 #include<cmath>
      4 #include<cstring>
      5 #include<map>
      6 #include<set>
      7 #include<vector>
      8 #include<algorithm>
      9 #include<queue>
     10 #include<unordered_map>
     11 using namespace std;
     12 #define ll long long 
     13 const int mod=1e9+7;
     14 const int inf=1e9+7;
     15  
     16 const int maxn=1e9-1;
     17  
     18 int nextt[4][2]={{-1,0},{0,1},{0,-1},{1,0}};//左上下,右 
     19  
     20 int main()
     21 {
     22     ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
     23     int T;
     24     cin>>T;
     25     int hei,bai;
     26     while(T--)
     27     {
     28         cin>>hei>>bai;//输入黑格子数,白格子数 
     29         int x,y,tx,ty,nowx,nowy;
     30         vector<pair<int,int>>v_hei;//装黑格坐标 
     31         vector<pair<int,int>>v_bai;//装白格坐标 
     32         map<pair<int,int>,int>book;//标记走过的坐标 
     33         if(hei>=bai)// 黑格子数多 
     34         {
     35             x=2;
     36             y=2;
     37         }
     38         else
     39         {
     40             swap(hei,bai);//交换
     41             x=2;             //和上面情况相同
     42             y=3;
     43         }
     44         if(hei>bai*3+1)//不符合
     45         {
     46             cout<<"NO"<<endl;
     47             continue;
     48         }
     49         //第一个白格坐标
     50         //黑格子数多,以白格子数为中心,周围放黑格子
     51         book[{x,y}]=1;
     52         v_bai.push_back({x,y});
     53         bai--;//剩下需要的白格数减一 
     54         while(bai>0)//当白格数大于0
     55         {
     56             for(int i=0;i<3;i++)
     57             {
     58                 tx=x+nextt[i][0];
     59                 ty=y+nextt[i][1];
     60                 if(tx<1||tx>maxn||ty<1||ty>maxn)
     61                     continue;
     62                 if(book[{tx,ty}]==0)
     63                 {
     64                     book[{tx,ty}]=1;
     65                     v_hei.push_back({tx,ty});
     66                     hei--;
     67                     if(hei==0)
     68                         break;
     69                 }
     70             }
     71             if(hei==0)//不需要黑格子了,退出 
     72                 break;
     73             if(bai>0)
     74             {
     75                 x+=2;//白格子现在坐标向右移动 
     76                 //y+=0;
     77                 v_bai.push_back({x,y});
     78                 book[{x,y}]=1;
     79                 bai--; 
     80             }
     81          }
     82          while(hei>0)//退出后还需要黑格子,在上次的白格子周围找
     83          {
     84              for(int i=0;i<v_bai.size();i++)
     85              {
     86                  x=v_bai[i].first;
     87                  y=v_bai[i].second;
     88                  for(int j=0;j<4;j++)
     89                  {
     90                      tx=x+nextt[j][0];
     91                      ty=y+nextt[j][1];
     92                     if(tx<1||tx>maxn||ty<1||ty>maxn)
     93                         continue;
     94                     if(book[{tx,ty}]==0)
     95                     {
     96                         book[{tx,ty}]=1;
     97                         v_hei.push_back({tx,ty});
     98                         hei--;
     99                         if(hei==0)
    100                             break;
    101                     }
    102                  }
    103                  if(hei==0)
    104                      break;
    105              }
    106           } 
    107          while(bai>0)//退出后还需要白格子,在上次的黑格子周围找 
    108          {
    109              for(int i=0;i<v_hei.size();i++)
    110              {
    111                  x=v_hei[i].first;
    112                  y=v_hei[i].second;
    113                  for(int j=0;j<4;j++)
    114                  {
    115                      tx=x+nextt[j][0];
    116                      ty=y+nextt[j][1];
    117                     if(tx<1||tx>maxn||ty<1||ty>maxn)
    118                         continue;
    119                     if(book[{tx,ty}]==0)
    120                     {
    121                         book[{tx,ty}]=1;
    122                         v_bai.push_back({tx,ty});
    123                         bai--;
    124                         if(bai==0)
    125                             break;
    126                     }
    127                  }
    128                  if(bai==0)
    129                      break;
    130              }
    131           }
    132         cout<<"YES"<<endl;
    133         for(int i=0;i<v_bai.size();i++)
    134             cout<<v_bai[i].first<<" "<<v_bai[i].second<<endl;
    135         for(int i=0;i<v_hei.size();i++)
    136             cout<<v_hei[i].first<<" "<<v_hei[i].second<<endl;    
    137     }
    138     
    139     return 0;    
    140 }            
    大佬见笑,,
  • 相关阅读:
    Linux学习之路——ls命令及文件权限
    解析规范格式的日志文件至List中
    Flask
    GIT和github
    常见的面试题
    python—面向对象的封装
    作业—数据类型8.20
    练习—8.17 while循环
    s7day2
    oracle 开窗分析函数和树形结构
  • 原文地址:https://www.cnblogs.com/xwl3109377858/p/11272146.html
Copyright © 2020-2023  润新知