Points Construction Problem(构造)
思路:构造。
考虑:如下无解的情况。
1.每个黑格子的贡献只能是 ,所以答案只能是偶数。
2.且 个格子最多贡献 个,则必须满足 。
3.考虑我们能构造 的下界:
一条长为 的直链的贡献为: ,一条长为 ,宽为 ,形如 的链贡献为: ,显然若成为一个长为 ,宽为 的矩阵后贡献仍然不变,因为每增加一个格子,贡献 是不影响的,所以需要满足 ,且 最小。
由基本不等式可知: 。
所以 。即当 是无解的。
接下来分两种情况构造:
。
我们可以构造一条一直链和若干个贡献为 的点。
设贡献为 的点个数为 ,则直链长度为 。
总贡献为:
因为 为偶数,显然 必定有解。
的情况。
考虑类比无解的情况 。
我们构造一条 形状的链,然后不断填充就可以了。
即:用 个点构造出 贡献,然后剩下的点 用来填充矩形即可。
。
即我们构造出长和宽和为 的 链,用 个点 ,显然是有解的。
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1e3+5,M=2e4+5,inf=0x3f3f3f3f,mod=1e9+7;
#define mst(a) memset(a,0,sizeof a)
#define lx x<<1
#define rx x<<1|1
#define reg register
#define PII pair<int,int>
#define fi first
#define se second
#define pb push_back
int main(){
int t;
scanf("%d",&t);
while(t--){
int n,m;
scanf("%d%d",&n,&m);
if(m&1||m>4*n||n*16>m*m) puts("No");
else {
puts("Yes");
if(m>2*n+2){
int x=(m-(2*n+2))/2,y=n-x;
for(int i=1;i<=x;i++) printf("1 %d\n",(i<<1));
for(int i=1;i<=y;i++) printf("3 %d\n",i);
}
else {
int x=m/4,y=m/2-x;
for(int i=1;i<=x;i++) printf("%d 1\n",i);
for(int j=2;j<=y;j++) printf("1 %d\n",j);
int rest=n-(x+y-1);
for(int i=2;i<=x&&rest>0;i++)
for(int j=2;j<=y&&rest>0;j++,rest--)
printf("%d %d\n",i,j);
}
}
}
return 0;
}