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);
}
}