牛客多校第三場 D- Points Construction Problem(構造)
阿新 • • 發佈:2020-07-20
牛客多校第三場 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\)
程式碼:
#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\n",i,1); } num4--; for(int i=1;i<=num4;i++){ printf("%d %d\n",-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\n"); 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\n",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\n",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\n",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\n",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\n",x,y); cnt++; } } else if(turn==1){//上轉右 while(cnt<n){ x++; printf("%d %d\n",x,y); cnt++; } } else if(turn==2){//左轉上 while(cnt<n){ y++; printf("%d %d\n",x,y); cnt++; } } else if(turn==3){//下轉左 while(cnt<n){ x--; printf("%d %d\n",x,y); cnt++; } } } } } }