竞赛准备篇---(四)子集生成
二进制枚举
用n位二进制数表示一个集合的状态,全部为1表示全集,全部为0表示空集,比如集合{0, 1,2,3};那我就可以用数字0-15的来表示集合的各个子集,用二进制从右往左数的第i为表示集合中第i个元素的状态。
数字 | 二进制 | 集合 |
0 | 0000 | 空集 |
1 | 0001 | 0 |
2 | 0010 | 1 |
3 | 0011 | 0,1 |
4 | 0100 | 2 |
5 | 0101 | 0,2 |
6 | 0110 | 1,2 |
7 | 0111 | 0,1,2 |
8 | 1000 | 3 |
9 | 1001 | 0,3 |
10 | 1010 | 1,3 |
11 | 1011 | 0,1,3 |
12 | 1100 | 2,3 |
13 | 1101 | 0,2,3 |
14 | 1110 | 1,2,3 |
15 | 1111 |
0,1,2,3 |
1 void print_subset(int n, int s) 2 { 3 for(int i = 0; i < n; i++) 4 if(s&(1<<i))printf("%d ", a[i]); 5 printf("\n"); 6 } 7 8 9 for(int i = 0; i < (1 << n); i++) 10 print_subset(n, i);
这里用整数表示集合
集合A,B相交:A&B(二进制的&运算就可以直接完成)
集合A,B相并:A|B
集合A,B的对称差:A^B
越努力,越幸运