Codeforces 1196E. Connected Component on a Chessboard

落爺英雄遲暮 提交于 2019-11-30 16:05:20

传送门

注意到棋盘可以看成无限大的,那么只要考虑如何构造一个尽可能合法的情况

不妨假设需要的白色格子比黑色格子少

那么容易发现最好的情况之一就是白色排一排然后中间黑的先连起来,剩下黑色的再全部填白色周围

可以证明如果需要 $w$ 个白色格子,那么黑色格子的数量不能超过 $3w+1$

证明:首先 $w=1$ 时显然

然后考虑下一个白色格子扩展,显然从一边延伸出去,然后又多了 $3$ 个可以放黑色的位置,这样一路扩展显然可以放 $3w+1$ 个黑色的位置

然后考虑证明没有更好的方案,显然除了第一次白色可以提供四个黑色位置以外,之后放扩展白色时,至少要有其中一边和原本的黑色相邻,那么每次扩展多就只能多 $3$ 个合法位置

证明完毕

然后直接按构造的搞就行了,注意一下细节就行

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
using namespace std;
typedef long long ll;
inline int read()
{
    int x=0,f=1; char ch=getchar();
    while(ch<'0'||ch>'9') { if(ch=='-') f=-1; ch=getchar(); }
    while(ch>='0'&&ch<='9') { x=(x<<1)+(x<<3)+(ch^48); ch=getchar(); }
    return x*f;
}
int Q,b,w;
inline bool pd(int x,int y) { return (x+y)&1; }
int main()
{
    Q=read();
    while(Q--)
    {
        b=read(),w=read();
        if(b>3*w+1||w>3*b+1) { printf("NO\n"); continue; }
        printf("YES\n"); int px,py,l;
        if(w>=b) px=py=2;
        else px=2,py=3;
        l=py;
        while(w||b)
        {
            if(pd(px,py))
            {
                if(!b) { py--; break; }
                b--;
            }
            else
            {
                if(!w) { py--; break; }
                w--;
            }
            printf("%d %d\n",px,py);
            py++;
        }
        for(int i=l;i<=py;i++)
        {
            if(pd(px,i)&&w)
            {
                printf("%d %d\n",px-1,i); w--;
                if(w) printf("%d %d\n",px+1,i),w--;
            }
            if((!pd(px,i))&&b)
            {
                printf("%d %d\n",px-1,i); b--;
                if(b) printf("%d %d\n",px+1,i),b--;
            }
        }
        if(b||w) printf("%d %d\n",px,py+1);
    }
    return 0;
}

 

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!