看了Matrix67神牛的位运算简介及实用技巧(三):进阶篇(2),下面是我写的C语言代码和我的思考作补充:
1 //By LYLtim 2 3 #include<stdio.h> 4 5 const unsigned upperlim = (1 << 8) - 1; 6 unsigned ans = 0; 7 8 void DFS(unsigned row, unsigned ld, unsigned rd) 9 { 10 if (row != upperlim) { 11 unsigned pos = upperlim & ~(row | ld | rd), p; 12 while (pos) { 13 p = pos & -pos; 14 pos -= p; 15 DFS(row | p, (ld | p) << 1, (rd | p) >> 1); 16 } 17 } else ans += 1; 18 } 19 20 int main(void) 21 { 22 DFS(0, 0, 0); 23 printf("%d\n", ans); 24 }
- -a=~a+1
见位运算简介及实用技巧(一):基础篇的整数类型的储存
这里我画个表格简单表示一下
0X0000 | …… | 0X7FFFF | 0X8000 | …… | 0XFFFF |
0 | …… | 32767 | -32768 | …… | -1 |
- pos & (~pos + 1) 是取出最右边的那个1
pos & ~pos 所有位全0,+1改变最低位:
(i)最低位为0:~0=1,1+1=10,前位进1,0&0=0,此位为0不变;
(ii)最低位为1:~1=0,0+1=1,其他位全为0不变,1&1=1,此位为1;
- &upperlim
这个我看时最难理解,任何位&1都是它本身,这有何作用?
后来明白了,作用就是从最低位起取n个数为有效位置,因为在上一次的运算中ld发生了左移,如果不and的话,就会误把n位左边的位当做有效位,n位左边有1就会发生错误。