【AtCoder Grand Contest 025 D】Choosing Points
构造。
题目大意:
给定 $2n\times 2n$ 的二维平面,给出整数 $D_1,D_2$,要求找到 $n^2$ 个整点,使得它们两两的欧几里得距离都不为 $\sqrt{D_1}$ 或 $\sqrt{D_2}$。
题解:
考虑只有一个限制 $D$ 的情况。这时我们有一张二分图,即可以通过对二维平面黑白染色,使得同色点之间的距离均不为 $\sqrt D$。
考虑 $D\bmod 4$ 的值。
若 $D\bmod 4=1$,则说明横、纵坐标一奇一偶,此时按照棋盘染色即可。
若 $D\bmod 4=2$,则说明横、纵坐标均为奇数,此时按照行(或列)标号,每行(或列)染成同一种颜色即可。
若 $D\bmod 4=0$,则我们把 $2\times 2$ 的区域染成同一种颜色,然后相当于考虑 $\frac D 4$ 的子问题。
我们取同色点即可满足条件。
考虑有两个限制的情况。也就是说我们要求两种不同染色都一样的点。由于一共有 $4n^2$ 种点,有 $4$ 种不同染色情况,由抽屉原理可知一定有解。
染色可以 $O(n^2)$ 完成。
Code:
#include<bits/stdc++.h>
int n,d1,d2,color[606][606],N;
void paint(int d){
int b=0;
while(!(d&3))d>>=2,++b;
if(d&1){
for(int i=0;i<N;++i)
for(int j=0;j<N;++j)
if(((i>>b)+(j>>b))&1)color[i][j]=1;
}else{
for(int i=0;i<N;++i)
for(int j=0;j<N;++j)
if((i>>b)&1)color[i][j]=1;
}
}
int main(){
scanf("%d%d%d",&n,&d1,&d2);
N=n<<1;
paint(d1),paint(d2);
int NN=n*n;
for(int i=0;i<N;++i)
for(int j=0;j<N;++j)
if(!color[i][j]){
printf("%d %d\n",i,j);
if(!--NN)return 0;
}
}