https://ac.nowcoder.com/acm/contest/5668/G
可以知道m其实就是所有的周长
所以枚举一个长度a,b,2*a+2*b=m,表示必须在这个矩阵内,然后先染对角线上的点Min(a,b)个点,就保证了周长,然后用bfs去拓展染色点,不能拓展出边界
#include<bits/stdc++.h>
using namespace std;
int vis[105][105];
int arr[4][2]={0,1,0,-1,1,0,-1,0};
int main(){
int t;
scanf("%d",&t);
while(t--){
int n,m;
scanf("%d%d",&n,&m);
if(m&1)printf("No\n");
else{
m>>=1;
int f=0;
for(int a=1;2*a<=m;a++){
int b=m-a;
if(n>=b&&n<=a*b){
f=1;
printf("Yes\n");
int cnt=0;
queue<int>q;
for(int i=1;i<=a;i++){
for(int j=1;j<=b;j++)vis[i][j]=0;
}
for(int i=1;i<=b;i++){
int x=min(i,a),y=min(i,b);
printf("%d %d\n",x,y);
vis[x][y]=1;
for(int j=0;j<4;j++){
int tx=x+arr[j][0],ty=y+arr[j][1];
if(tx>=1&&tx<=a&&ty>=1&&ty<=b&&!vis[tx][ty])q.push(tx),q.push(ty);
}
cnt++;
}
while(cnt!=n){
int x=q.front();q.pop();
int y=q.front();q.pop();
if(vis[x][y])continue;
vis[x][y]=1;
printf("%d %d\n",x,y);
cnt++;
for(int j=0;j<4;j++){
int tx=x+arr[j][0],ty=y+arr[j][1];
if(tx>=1&&tx<=a&&ty>=1&&ty<=b&&!vis[tx][ty])q.push(tx),q.push(ty);
}
}
break;
}
}
if(f==0)printf("No\n");
}
}
}