[uva] 729 - The Hamming Distance Problem

0-1子集生成问题
本文探讨0-1子集生成问题,并提供两种实现方法:二进制方法和深度优先搜索(DFS)方法。文章详细解释了如何通过这两种方法控制1的个数并按字典序输出解。此外还特别注意到了输出格式的要求。

http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=670

这道题 就是0-1的子集生成嘛, 无非是控制一下1的个数就好, 但是遇到的问题是怎么按照字典序输出,

好吧, 我沙茶 我用的最笨的方法, 得出一个解就塞到vector里,然后sort一下,一起输出......

后来一想, 子集生成还有二进制的方法, 不需要什么vector了!

这道题还要注意的是输出格式: "Print a blank line between datasets.". 每两个输出之间要有空行, 最后一个输出后面不要有空行. 因为这个贡献2Wa.

下面给出两种方法的代码, 其实就是子集生成的两种代码.

方法一:(二进制方法子集生成)

 1 #include <cstdio>
 2 #include <vector>
 3 #include <string>
 4 #include <algorithm>
 5 using namespace std;
 6 int hnum = 0;
 7 int n = 0;
 8 int getOneNum(int num) {
 9     int cnt = 0;
10     for (int i = 0; i < n; ++i) {
11         if (num & 0x0001) {
12             cnt += 1;
13         }
14         num >>= 1;
15     }
16     return cnt;
17 }
18 
19 void printSet(int num, int bnum) {
20     if (bnum == n) {
21         return;
22     }
23     printSet(num >> 1, bnum + 1);
24     printf("%d", num & 0x0001);
25     
26 }
27 
28 int main(int argc, const char * argv[])
29 {
30     int t = 0;
31     scanf("%d", &t);
32     for (int i = 0; i < t; ++i) {
33         scanf("%d%d", &n, &hnum);
34         for (unsigned int i = 0; i <= (1 << n); ++i) {
35             if (hnum == getOneNum(i)) {
36                 printSet(i, 0);
37                 printf("\n");
38             }
39         }
40         if (i != t - 1) {
41             printf("\n");
42         }
43     }
44     return 0;
45 }

 

方法二:(dfs)

 1 #include <cstdio>
 2 #include <vector>
 3 #include <string>
 4 #include <algorithm>
 5 using namespace std;
 6 
 7 string ham;
 8 int hnum = 0;
 9 int n = 0;
10 vector<string> re;
11 
12 void solve(int cur, int onenum) {
13     if (cur < 0) {
14         if (count(ham.begin(), ham.end(), '1') == hnum) {
15             re.push_back(ham);
16         }
17     } else {
18         if (onenum < hnum) {
19             ham[cur] = '1';
20             solve(cur - 1, onenum + 1);
21         }
22         ham[cur] = '0';
23         solve(cur - 1, onenum);
24     }
25 }
26 
27 int main(int argc, const char * argv[])
28 {
29     int t = 0;
30     scanf("%d", &t);
31     for (int i = 0; i < t; ++i) {
32         scanf("%d%d", &n, &hnum);
33         string tmp(n, '0');
34         ham = tmp;
35         re.clear();
36         solve((unsigned int)ham.size() - 1, 0);
37         sort(re.begin(), re.end());
38         for (unsigned int i = 0; i < re.size(); ++i) {
39             printf("%s\n", re[i].c_str());
40         }
41         if (i != t -1) {
42             printf("\n");
43         }
44     }
45     return 0;
46 }

 

转载于:https://www.cnblogs.com/NextLife/p/3464260.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值