Connected Component on a Chessboard(CF-1196E)

Problem Description

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

Your task is to find a connected component on this chessboard that contains exactly bb black cells and exactly ww 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 cici from 11 to kk are belong to this set of cells and for every i∈[1,k−1], cells cici and ci+1ci+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 qq independent queries.

Input

The first line of the input contains one integer q (1≤q≤105) — the number of queries. Then qq 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+wb+w lines print coordinates of cells of your component in any order. There should be exactly bb black cells and ww 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].

Examples

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

题意:q 组询问,每组给出 n 个黑块 m 个白块,现在有一个起点 (1,1) 为白色的黑白交叉的棋盘,现在要在这个棋盘上将 n 个黑块和 m 个白块放置在其上,使得这 n+m 个块的颜色与棋盘颜色相同而且连通,如果能放置成功,输出 YES 并任意输出一种放置方案,如果不能放置输出 NO

思路:

1 个黑块最多能连通 4 个白块,2 个黑块最多能连通 7 个白块,3 个黑块最多能连通 10 个黑块,以此类推,n 个黑块最多能连通 3*m+1 个白块,反之同理,m 个白块最多能连通 3*n+1 个黑块,因此当 n、m 的关系不满足上述结论时,输出 NO 即可

由于棋盘的空间最大能到 1E9,黑白块个数和不超过 2E5 且黑白块的位置可以随意放置,因此可以一个点为基准,向下依次放置黑白块

考虑 n、m 的大小,有三种情况:

n=m 时,以任意点为起点,依次向下顺序排列即可

n>m 时:需要以白块为基准,从上到下依次放置 m 个白块 m 个黑块,剩下 sub=n-m 个黑块,若 sub 为偶数时,从上到下依次放置到之前的 2m 块棋盘两端,若 sub 为奇数时,需要将多余的一个黑块放置在一白块的两端

n<m 时:需要以黑块为基准,从上到下依次放置 n 个白块 n 个黑块,剩下 sub=m-n 个黑块,若 sub 为偶数时,从上到下依次放置到之前的 2n 块棋盘两端,若 sub 为奇数时,需要将多余的一个白块放置在一黑块的两端

需要注意的是,当 n=3*m+1 或 m=3*n+1 时,说明 n 个黑块或 m 个白块周围已经被放满,此时最上面的一个格子同样需要放置

​​​​​​​

Source Program

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<string>
#include<cstring>
#include<cmath>
#include<ctime>
#include<algorithm>
#include<utility>
#include<stack>
#include<queue>
#include<vector>
#include<set>
#include<map>
#include<bitset>
#define EPS 1e-9
#define PI acos(-1.0)
#define INF 0x3f3f3f3f
#define LL long long
const int MOD = 1E9+7;
const int N = 500000+5;
const int dx[] = {-1,1,0,0,-1,-1,1,1};
const int dy[] = {0,0,-1,1,-1,1,-1,1};
using namespace std;
char str[N];
char t[N];
int a[N];
int sum[N];
int main(){
    int q;
    scanf("%d",&q);
    while(q--){
        int n,m;
        scanf("%d%d",&n,&m);

        if(m>3*n+1||n>3*m+1)
            printf("NO\n");
        else{
            printf("YES\n");
            if(n==m){
                for(int i=2;i<=2*n+1;i++)
                    printf("2 %d\n",i);
            }
            else if(n>m){
                int sub=n-m;

                if(n==3*m+1){
                    sub--;
                    printf("2 1\n");
                }

                for(int i=2;i<=2*m+1;i++)
                    printf("2 %d\n",i);

                int i=1;
                while(sub>1){
                    int temp=2*i;
                    printf("1 %d\n",temp);
                    printf("3 %d\n",temp);
                    sub-=2;
                    i++;
                }
                if(sub==1)
                    printf("1 %d\n",2*i);
            }
            else if(n<m){
                int sub=m-n;
                if(m==3*n+1){
                    sub--;
                    printf("3 1\n");
                }

                for(int i=2;i<=2*n+1;i++)
                    printf("3 %d\n",i);

                int i=1;
                while(sub>1){
                    int temp=2*i;
                    printf("2 %d\n",temp);
                    printf("4 %d\n",temp);
                    sub-=2;
                    i++;
                }
                if(sub==1)
                    printf("2 %d\n",2*i);
            }
        }
    }
    return 0;
}

 

  • 4
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
好的,以下是代码形式的电话线路图状态: ``` @startuml title Telephone State Diagram [*] --> Idle : Initial State Idle --> Dialing : Off Hook Event Dialing --> Connecting : Valid Number Event Dialing --> Disconnected : Invalid/Wrong Number Event Connecting --> TimeOut : Timeout Event Connecting --> Connected : Called Phone Answers Event Ringing --> Connected : Called Phone Answers Event Connected --> Idle : On Hook Event Connected --> Busy Tone : Line Busy Event Connected --> TimeOut : Timeout Event Connected --> Disconnected : Timeout Event Connected --> Ringing : Play Message Event @enduml ``` 解释一下: - 初始状态为空闲状态(`[*] --> Idle : Initial State`)。 - 当电话机摘机时,电话状态从空闲状态转入拨号状态(`Idle --> Dialing : Off Hook Event`)。 - 当拨号有效号码时,电话状态从拨号状态转入连接状态(`Dialing --> Connecting : Valid Number Event`)。 - 当拨号号码无效或错误时,电话状态从拨号状态转入未连接状态(`Dialing --> Disconnected : Invalid/Wrong Number Event`)。 - 当连接超时时,电话连接状态从连接状态转入超时状态(`Connecting --> TimeOut : Timeout Event`)。 - 当被拨打的电话接听时,电话连接状态从连接状态或响铃状态转入已连接状态(`Connecting --> Connected : Called Phone Answers Event` 或 `Ringing --> Connected : Called Phone Answers Event`)。 - 当已连接状态的电话机挂机时,电话状态从已连接状态转入空闲状态(`Connected --> Idle : On Hook Event`)。 - 当已连接状态的电话线路忙碌时,电话状态从已连接状态转入忙音状态(`Connected --> Busy Tone : Line Busy Event`)。 - 当已连接状态的电话连接超时时,电话状态从已连接状态转入未连接状态(`Connected --> TimeOut : Timeout Event`)。 - 当已连接状态的电话播放信息时,电话状态从已连接状态转入响铃状态(`Connected --> Ringing : Play Message Event`)。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值