D-Points Construction Problem 2020牛客多校第3场

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

猜你喜欢

转载自blog.csdn.net/liufengwei1/article/details/107431546