题目: 求双色球的所有可能组合?

规则:红球32个,编号1~32;篮球16个,编号1~16。6个红球 + 1个篮球为1注,6个红球没有先后顺序。

 

本题重点在于从32个球里取6个球,其实就是求组合问题,至于篮球的选择则非常简单,下面主要集中解求组合问题。

 

最直接的想法是通过6重循环实现,代码如下:

 1 void enum_combination_loops(vector<vector<int>>& candidates, int redCount = 32, int redSelectCount = 6){
 2     for (int i = 1; i <= redCount - redSelectCount + 1; i++)
 3         for (int j = i + 1; j <= redCount - redSelectCount + 2; j++)
 4             for (int k = j + 1; k <= redCount - redSelectCount + 3; k++)
 5                 for (int m = k + 1; m <= redCount - redSelectCount + 4; m++)
 6                     for (int n = m + 1; n <= redCount - redSelectCount + 5; n++)
 7                         for (int l = n + 1; l <= redCount; l++)
 8                         {
 9                             vector<int> tmp;
10                             tmp.push_back(i);
11                             tmp.push_back(j);
12                             tmp.push_back(k);
13                             tmp.push_back(m);
14                             tmp.push_back(n);
15                             tmp.push_back(l);
16                             candidates.push_back(tmp);
17                         }
18 }
View Code

 

那有没有更优的方法呢,因为是枚举问题,鄙人认为这已经是比较优的解法了,欢迎拍砖,欢迎指出更好的办法。

 

那这个能不能换一种写法呢,让代码看上去不那么恐怖(n重循环总是给人一种很恐怖的感觉,尽管有时是一种比较高效的解法),答案当然是有的,下面直接贴出代码:

 1 void enum_combination_recursive(vector<vector<int>>& candidates, vector<int> candidate, int index, int totalCount, int others){
 2     if (index + others > totalCount + 1)
 3     {
 4         return;
 5     }
 6     if (others == 1) {
 7         for (int i = index; i <= totalCount; i++)
 8         {
 9             vector<int> tmp(candidate);
10             tmp.push_back(i);
11             candidates.push_back(tmp);
12         }
13         
14         return;
15     }
16     candidate.push_back(index);
17     enum_combination_recursive(candidates, candidate, index + 1, totalCount, others - 1);
18     candidate.pop_back();
19     enum_combination_recursive(candidates, candidate, index + 1, totalCount, others);
20 }
View Code

 

但实际上递归的方法的时间消耗是更大的,毕竟每次递归操作会有函数地址及参数压栈出栈的时间消耗,下图实验结果显示确实递归方法会耗时不少:

 

 

本题考查的是代码编写能力,而不是问题解决能力,以更简洁的代码实现问题解是程序员的基本素养。