(〃’▽’〃)
题解:
这种题看起来很简单,题解一看谁都会做,主要是考一种思考的过程,希望有帮助吧。
我们认为
(0,0)
一定可取,然后按照
2
个
d
来标记整张图。
先假设
d2=a2+b2(a,b⊆R)
,这样只会多标记而不会漏掉。
Case:
d
mod
2=1
,
a
和
b
一定一奇一偶,按国际象棋标记即可。
定左上角为
(0,0)
。
0101010101101010101001010101011010101010010101010110101010100101010101101010101001010101011010101010
d
mod
4=2
,
a
和
b
一定都是奇数,隔一行标记一行即可。
0101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101
d
mod
4=0
,此时
x2=y2+z2(x=d4,y=a2,z=b2)
。把
d,a,b
分别变成
x,y,z
(相当于把
2×2
的区域看成一个格子),再进行上述操作即可。
0011001100001100110011001100111100110011001100110000110011001100110011110011001100110011000011001100
以下是
d=16
的情况。
0000111100000011110000001111000000111100111100001111110000111111000011111100001100001111000000111100
两个
d
分别处理以下,标记叠加后为
0
的就是可以放的,易证明空余位置一定是多于
n2
的。任意取
n2
个即可。
Code:
using namespace std;
int f[N][N],n;
void work(int d)
{
int t=0;
while(d%4==0)
{
t++;
d/=4;
}
if(d%2==1)
{
for(int i=0;i<2*n;i++)
for(int j=0;j<2*n;j++)
if(((i>>t)+(j>>t))%2==1)f[i][j]=1;
}
if(d%4==2)
{
for(int i=0;i<2*n;i++)
for(int j=0;j<2*n;j++)
if((i>>t)%2==1)f[i][j]=1;
}
}
int main()
{
int d1,d2;
scanf("%d%d%d",&n,&d1,&d2);
memset(f,0,sizeof(f));
work(d1);work(d2);
int sum=0;
for(int i=0;i<2*n;i++)
for(int j=0;j<2*n;j++)
if(!f[i][j])
{
printf("%d %d\n",i,j);
sum++;
if(sum==n*n)return 0;
}
}