给出一个数字列表有多少种方法可以得到21?如何获得所有可能的数字组合?

时间:2014-03-23 14:01:51

标签: c++ arrays numbers combinations

好的,所以我必须解决这个问题,其中用户提供了7个或k个数字的列表,我必须说明有多少种方法可以获得21或{{1使用这些数字的和和减法。 我必须使用所有数字。
例如,用户给出数字:(1 3 4 5 9 1 7)。我可以将所有这些数字放入一个长度为7的数组中,并计算我使用这些数字的总和和/或子数的次数: n

此问题的代码已经完成:

1 +/- 3 +/- 4 +/- 5 +/- 9 +/- 1 +/- 7

正如你所看到的,这使得DFS(深度优先搜索)能够找到有多少种方法可以获得21.现在,实际问题是如何知道有多少种方法可以获得21 使用给定数字的组合,我必须再次使用它们。例如,用户提供数字:

count-twenty-one(int* dig, int n, int pos, int sum, int res) { if (pos==n) { if(sum==21) return res++; } count-twenty-one(dig, n, pos+1, sum+dig[pos], res) count-twenty-one(dig, n, pos+1, sum-dig[pos], res) } 。我无法使用0 + 0 - 0 + 0 + 2 + 1 + 0来获得21但是如果我将2和1和sum / sub与其他0相加,我可以得到21。 (0 0 0 0 2 1 0)让我们说用户现在给出(2 3 9 8 5 0 7)。有了这个,我可以使用0 + 0 + 0 - 0 + 21 -0 = 21这样的数字,并尝试查看有多少种方法可以获得所需的数字。但是我可以再次23 98 5 7

所以我猜主要的问题是从(1到k)获得所有可能的数字组合 - K是数字列表的长度 - 然后在所有的数字中使用239 8 507他们。我该怎么做呢?我正在使用C ++和数组。

修改

可以通过获取给定数组的所有可能分区来解决此问题,然后通过count-twenty-one将这些分区放入其中。有什么想法吗?

编辑2 : 这些号码已被排序'这意味着使用count-twenty-one,我无法形成(2 3 9 8 5 0 7)

等组合

1 个答案:

答案 0 :(得分:0)

对于蛮力方法,以下内容可能有所帮助:https://ideone.com/jAVRDk

void print(const std::vector<int>& digits,
           const std::vector<int>& seps,
           const std::vector<std::string>& s) {
    std::cout << digits[0];
    for (std::size_t i = 0; i != seps.size(); ++i) {
        std::cout << s[seps[i]] << digits[i + 1] ;
    }
    std::cout << std::endl;
}

bool next(std::vector<int>& seps)
{
    for (auto it = seps.rbegin(); it != seps.rend(); ++it) {
        if (++*it == 3) {
            *it = 0;
        } else {
            return true;
        }
    }
    return false;
}

void foo(std::vector<int> digits)
{
    const std::vector<std::string> s = {"", " + ", " - "};
    std::sort(digits.begin(), digits.end());

    do {
        std::vector<int> seps(digits.size() - 1, 0);

        do {
            print(digits, seps, s);
        } while (next(seps));
    } while (std::next_permutation(digits.begin(), digits.end()));

}