- import stdio
- import stdarray
- import sys
- n = int(sys.argv[1])
- a = stdarray.create2D(n, n, 0)
- for i in range(n):
- for j in range(n):
- temp = i & j
- count = 0
- for k in range(8):
- count += (temp >> k) & 1
- if count % 2 == 0:
- a[i][j] = 1
- else:
- a[i][j] = 0
- for i in range(n):
- for j in range(n):
- stdio.write(a[i][j])
- stdio.write(' ')
- stdio.writeln()
大家问的最多的,肯定是代码的思路了,想知道为什么吗?一起来看吧。
- temp = i & j
- count = 0
- for k in range(8):
- count += (temp >> k) & 1
- if count % 2 == 0:
- a[i][j] = 1
- else:
- a[i][j] = 0
它是干啥的呢?
它的意思是,看temp的2进制形式里,有几个1,如果有偶数个1,那么a[i][j]=1;如果有奇数个1,那么a[i][j]=0。
为什么要用这个方法呢?
因为这个方法是我们看到了一个现象,猜测可能是这个结论,结果一验证果真如此,就很开心。
那你们看到了什么现象呢?
我们先观察,在
1 1
1 0
这个矩阵中,a[0][0]、a[0][1]、a[1][0]都是1,而a[1][1]是0。观察之后,发现:
0&0=0,0&1=0,1&0=0,1&1=1
这还不足以让我们产生灵感,所以我们就再观察:
1 1 1 1
1 0 1 0
1 1 0 0
1 0 0 1
原来a[1][1]位置的数,跑到了a[3][1],它的横坐标加了2,放十进制来看,确实不方便,但放二进制来看,就很一目了然了。为什么说它一目了然呢?因为横坐标从0001,变成了0011,但纵坐标没变,所以横纵坐标取并之后,a[3][1]还是1。
同样的道理,原来a[1][1]位置的数,也跑到了a[1][3],它的纵坐标加了2,放十进制来看,确实不方便,那就从二进制来看,纵坐标从0001,变成了0011,但横坐标没变,还是0001,所以横纵坐标取并,结果是0001,所以a[1][3]也还是1。
但如果横纵坐标都加了2呢?我们看,当a[1][1]跑到了a[3][3],横纵坐标均加了2之后,就变成了0,是巧合吗?我们再试一试:a[0][0]是1,a[2][2]是0;a[0][1]是1,a[2][3]是0......
从这个现象,我们猜测:如果i&j的二进制形式里,有奇数个1,那么a[i][j]就是0;而如果有偶数个1,那么a[i][j]就是1。
经过验证,发现果真如此!当我们验证发现完全正确时,说实话高兴坏了!!!