• 牛客多校第三场 D- Points Construction Problem(构造)


    牛客多校第三场 D- Points Construction Problem

    链接: Points Construction Problem

    题意:

    在2D平面内,每个格点(整数点)有一个白点,可以将其中一些点涂黑。

    问能否将n个白点涂黑,使得有m对相邻的白点和黑点(指哈夫曼距离为1)

    解法:

    (1)若每个黑点都是不相邻的,则可以发现涂黑n个的黑白对数上限为4*n。

    (2)如果每个黑点相邻,并排成一行,则此时黑白对数为2*n+2。

    (3)可以发现黑白点对数一定是偶数,在(2)的基础上,将链上的黑点逐个拿出并放置在互不相邻处,则可以实现(2*n+2)(4*n)所有偶数m的构造。

    (4)如果m比(2*n+2)还要小,可以在(2)的基础上,将这条黑点链逐步卷曲来减少黑白点对数,每次减2,如下图:

    1595234997186

    代码:

    #include <bits/stdc++.h>
    using namespace std;
    int vis[100][100];
    int f(int u,int v){//周围黑点个数
        return vis[u-1][v]+vis[u+1][v]+vis[u][v+1]+vis[u][v-1];
    }
    int main () {
        int t;
        scanf("%d",&t);
        while(t--){
            int n,m;
            scanf("%d%d",&n,&m);
            if(n*4<m || m%2==1){
                puts("No");
                continue;
            }
            int srt=sqrt(n);
            int rest=n-srt*srt;
            int down=srt*4;
            if(rest>0){
                down+=2;
            }
            if(rest>srt){
                down+=2;
            }
            if(m<down){
                puts("No");
                continue;
            }
            puts("Yes");
            if((n*4-m)/2<n){//单链
                int num2=(n*4-m)/2;
                int num4=n-num2;
                for(int i=1;i<=num2+1;i++){
                    printf("%d %d
    ",i,1);
                }
                num4--;
                for(int i=1;i<=num4;i++){
                    printf("%d %d
    ",-i,-i);
                }
            }
            else{//进行卷
                memset(vis,0,sizeof vis);
                int num0=(2*n+2-m)/2;
                int cnt=0;
                vis[50][50]=1;
                cnt++;
                printf("50 50
    ");
                int x=50,y=50;
                int turn=0;//0右,1上,2左,3下
                for(int step=1;step<=10;step++){
                    for(int sstep=1;sstep<=2;sstep++){//同一步长走两次
                        if(turn==0){
                            for(int i=1;i<=step;i++){
                                x++;
                                vis[x][y]=1;
                                cnt++;
                                printf("%d %d
    ",x,y);
                                if(f(x,y)==2){
                                    num0--;
                                }
                                if(num0==0 ||cnt==n){
                                    break;
                                }
                            }
                            if(num0==0||cnt==n){
                                break;
                            }
                            turn=(turn+1)%4;
                        }
                        else if(turn==1){
                            for(int i=1;i<=step;i++){
                                y++;
                                vis[x][y]=1;
                                cnt++;
                                printf("%d %d
    ",x,y);
                                if(f(x,y)==2){
                                    num0--;
                                }
                                if(num0==0 ||cnt==n){
                                    break;
                                }
                            }
                            if(num0==0||cnt==n){
                                break;
                            }
                            turn=(turn+1)%4;
                        }
                        else if(turn==2){
                            for(int i=1;i<=step;i++){
                                x--;
                                vis[x][y]=1;
                                cnt++;
                                printf("%d %d
    ",x,y);
                                if(f(x,y)==2){
                                    num0--;
                                }
                                if(num0==0 ||cnt==n){
                                    break;
                                }
                            }
                            if(num0==0||cnt==n){
                                break;
                            }
                            turn=(turn+1)%4;
                        }
                        else if(turn==3){
                            for(int i=1;i<=step;i++){
                                y--;
                                vis[x][y]=1;
                                cnt++;
                                printf("%d %d
    ",x,y);
                                if(f(x,y)==2){
                                    num0--;
                                }
                                if(num0==0 ||cnt==n){
                                    break;
                                }
                            }
                            if(num0==0||cnt==n){
                                break;
                            }
                            turn=(turn+1)%4;
                        }
                    }
                    if(num0==0||cnt==n){
                        break;
                    }
                }
                if(cnt!=n){
                    if(turn==0){//右转下
                        while(cnt<n){
                            y--;
                            printf("%d %d
    ",x,y);
                            cnt++;
                        }
                    }
                    else if(turn==1){//上转右
                        while(cnt<n){
                            x++;
                            printf("%d %d
    ",x,y);
                            cnt++;
                        }
                    }
                    else if(turn==2){//左转上
                        while(cnt<n){
                            y++;
                            printf("%d %d
    ",x,y);
                            cnt++;
                        }
                    }
                    else if(turn==3){//下转左
                        while(cnt<n){
                            x--;
                            printf("%d %d
    ",x,y);
                            cnt++;
                        }
                    }
                }
            }
        }
    }
    
  • 相关阅读:
    kubeadm部署kubernetes
    一键部署redis-5.0.5
    二进制部署kubernetes高可用
    设计模式--行为型模式--观察者模式(Observer模式)
    设计模式--行为型模式--状态模式
    设计模式--行为型模式--责任链模式(职责链模式)
    《数学之美》在线阅读
    设计模式--行为型模式--命令模式
    设计模式--行为型模式--策略模式
    设计模式--行为型模式--模板方法模式
  • 原文地址:https://www.cnblogs.com/ucprer/p/13346013.html
Copyright © 2020-2023  润新知