基于2个变量的组合

时间:2010-12-04 17:39:40

标签: c combinatorics

我正在努力实现以下功能:

想象一下,我有1-9个方格。这些方块在全球范围内分配了一个数字,而不是单独分配。它们就像一个集合,该集合具有这个数字。

例如:| _ | _ | _ | 19

我想要做的是一个功能,它根据正方形的数量和与它们相关的数字给出了可能的组合。对于上面的示例:9,8,2是可能的组合之一。但是我只想要那些组合中的数字,而不是组合本身。另外,它们必须是唯一的(不应该是9,9,1)。哦,这些数字范围来自1-9

我怎样才能在C中实现这一目标?如果你想知道这是一个益智游戏。

提前致谢!

3 个答案:

答案 0 :(得分:1)

您似乎正在尝试在右侧找到受限制的Partition整数。该链接应该为您提供一个良好的起点,您应该能够找到一些生成整数分区为任意数量的部分的算法。

答案 1 :(得分:0)

听起来你正在做的事情与kakuro非常相似,也称为Cross Sums:http://en.wikipedia.org/wiki/Cross_Sums

这些类型的谜题都有发生器,例如:http://www.perlmonks.org/?node_id=550884

我怀疑大多数kakuro发电机必须解决你的确切问题,所以你可能会看一些来寻找灵感。

答案 2 :(得分:0)

为了将来参考,在组合学中我们说“顺序无关紧要”是指“我只想要一组数字,而不是特定的顺序”

//Sets the given digit array to contain the "first" set of numbers which sum to sum
void firstCombination(int digits[], int numDigits, int sum) { 
    reset(digits, 0, 1, numDigits, sum);
}

//Modifies the digit array to contain the "next" set of numbers with the same sum.
//Returns false when no more combinations left
int nextCombination(int digits[], int numDigits) {
    int i;
    int foundDiffering = 0;
    int remaining = 0;
    for (i = numDigits - 1; i > 0; i--) {
        remaining += digits[i];
        if (digits[i] - digits[i - 1] > 1) {
            if (foundDiffering || digits[i] - digits[i - 1] > 2) {
                digits[i - 1]++;
                remaining--;
                break;
            } else
                foundDiffering = 1;
        }
    }
    if (i == 0)
        return 0;
    else {
        reset(digits, i, digits[i - 1] + 1, numDigits - i, remaining);
        return 1;
    }
}

//Helper method for firstCombination and nextCombination
void reset(int digits[], int off, int lowestValue, int numDigits, int sum) {
    int i;
    int remaining = sum;
    for (i = 0; i < numDigits; i++) {
        digits[i + off] = lowestValue;
        remaining -= lowestValue;
        lowestValue++;
    }
    int currentDigit = 9;
    for (i = numDigits + off - 1; i >= off; i--) {
        if (remaining >= currentDigit - digits[i]) {
            remaining -= currentDigit - digits[i];
            digits[i] = currentDigit;
            currentDigit--;
        } else {
            digits[i] += remaining;
            break;
        }
    }
}