2020牛客暑期多校训练营第三场Points Construction Problem

Points Construction Problem

看原题请戳这里

题目大意:

假设您有一个具有笛卡尔坐标系的无限二维平面。 最初,所有整数点(xy坐标都为整数的点)都绘制为白色。 给出两个整数n和m。 请精确地将n个整数点涂成黑色,使得刚好有m个点对满足以下条件:
1.这两点用不同的颜色着色。
2.这两点相邻。 我们称两个整数点(x1,y1)和(x2,y2)相邻,当且仅当∣x1-x2∣ + ∣y1 −y2∣ = 1.
3.所有黑点的x和y坐标在[-10 ^ 9,10 ^ 9] 范围内.

输入:

第一行包含一个整数T(1≤T≤10^3),表示测试用例的数量.
每个测试用例包含两个整数n,m(1≤n≤50,1≤m≤200).

输出:

对于每个测试,如果存在至少一个方案来选择n个点以满足语句给出的条件,则应该输出n + 1行。 第一行包含一个字符串“Yes”,接下来的n行包含这n个点,这些点的颜色为黑色。 如果没有解决方案,请打印仅包含一个字符串“ No”的一行。

样例输入:

6
5 20
1 2
1 3
1 4
1 5
3 8

样例输出:

Yes
1 1
2 2
3 3
4 4
5 5
No
No
Yes
1 1
No
Yes
1 1
1 2
2 1

代码:

#include<bits/stdc++.h>
using namespace std;
int x[4]={0,0,1,-1},
    y[4]={1,-1,0,0};
int t,n,m,v1,v2,cnt,sum,k,a[50][50];
int main()
{
    for(scanf("%d",&t);t--;sum=0)
    {
        v1=40;v2=40;
        scanf("%d%d",&n,&m);
        cnt=n;
        memset(a,0,sizeof(a));
        k=(int)(sqrt(n));
        if(k*k<n) k++;
        for(int i=2;i<=k+1;i++)
        {
            for(int j=2;j<=k+1;j++)
            {
                if(!cnt) break;
                else a[i][j]=1,cnt--;
            }
            if(!cnt) break;
        }
        for(int i=1;i<=10;i++)
            for(int j=1;j<=10;j++)
                for(int k=0;k<4;k++)
                    if(a[i][j]==0&&a[i+x[k]][j+y[k]]==1) sum++;
        if(sum>m||m%2||n*4<m){puts("No");continue;}
        puts("Yes");
        for(int i=k+1;i>=2;i--)
        {
            for(int j=k+1;j>=2;j--)
            {
                if(!a[i][j]) continue;
                if(sum==m) break;
                int p=v1,q=v2;
                if(j!=2&&i!=2)
                {
                    sum+=4;
                    a[i][j]=0;
                    a[v1][v2]=1;
                    v2-=2;
                    if(v2==0) v1-=2,v2=40;
                }
                else
                {
                    sum+=2;
                    a[i][j]=0;
                    a[v1][v2]=1;
                    v2-=2;
                    if(v2==0) v1-=2,v2=40;
                }
                if(sum>m)
                {
                    sum=m;
                    a[p][q]=0;
                    if(p==40&&q==40) a[1][2]=1;
                    else a[40][41]=1;
                }
            }
            if(sum==m) break;
        }
        for(int i=1;i<=45;i++)
            for(int j=1;j<=45;j++)
                if(a[i][j]==1) printf("%d %d\n",i,j);
    }
}

猜你喜欢

转载自blog.csdn.net/s260127ljy/article/details/107450225