【问题标题】:Finding the total number combinations for an integer using three numbers使用三个数字查找整数的总数组合
【发布时间】:2012-01-15 16:16:27
【问题描述】:

对于给定的整数 n,我需要打印所有长度为 3 且总和为 n 的列表。列表的成员必须是非负整数。打印完所有这些列表后,它必须打印找到的列表数。

例如,如果n=2

  • 1+0+1 = 2
  • 1+1+0 = 2
  • 0+1+1 = 2
  • 2+0+0 = 2
  • 0+0+2 = 2
  • 0+2+0 = 2

这是我为长度为 2 的列表而不是长度为 3 的列表所做的程序:

#include <stdio.h>
int main (void)
{
    int total;
    int c1=0;
    int c2=0;
    int c3=0;
    int count;

    printf("Welcome friends and mainly enemies to the thingy. Only postive intergers!!!\n That's right just enter a number here:");
    scanf ("%d",&total);
    printf ("\n\n\nWhy pick %d? Here is the list if combinations anyway,",total);

    for (count=0;count<=total;count++)
    {
        printf ("\n");
        for (c1=count;c1==count;c1--)
        {
            printf("%d ",c1);

        }
        for (c2=total-count;c2<=total-count;c2++)
        {
            printf("%d",c2);

        }

    }
    printf ("\n\nThere are %d number combinations that total %d",count,total);

}

目标是将其从长度为 2 的列表扩展到长度为 3 的列表。

附加信息: 我只能使用另一个变量 c3。

【问题讨论】:

  • 问题是我该怎么做。
  • 你的意思是“给定一个整数 n,打印所有长度为 m 且总和为 n 的列表。每个列表的成员都是非负整数。”
  • 是的,我相信这就是我的意思。如果按长度列表表示所有组合

标签: c algorithm


【解决方案1】:

希望这会有所帮助:

int c3 = 0;
for (int c1 = 0; c1 <= total; c1++) {       
    for (int c2 = total - c1; c2 >= 0; c2--){
        printf("%d %d %d \n", c1, c2, total - c1 - c2);
        c3++;
    }

}

printf("there are %d ways to sum to %d", c3, total);

【讨论】:

  • 这是不正确的。每个列表的 sum 必须正好为 2。请参阅问题末尾的示例。示例中只有 6 个列表。 (但我必须承认,一开始我对这个问题感到困惑!
  • ...也许只是把if(i+j+k==2) {printf ("%d %d %d", i, j, k);}放在中间。
  • 即使你这样做了,你也不会涵盖所有的组合。
  • 啊,你是对的。我确实误解了这个问题。 @Aaron McDaid:我正在编辑您添加的问题。
  • @TheMegalomaniac:实际上,代码(没有 if 语句)打印了一组 3 个 n 类型的所有可能排列。如果这不是您要寻找的答案,请编辑您的问题以准确说明您想要什么。
【解决方案2】:

如果您只对数字感兴趣,答案是与总重复 + 1 个元素的组合 第二类:让我解释一下:让我们考虑 total 1 的数量。他们有 total + 1 计算第一个 1 之前和最后一个之后的间隙之间的间隙。您正在尝试选择总和的 3 个数字:我们将通过在我刚刚解释的间隙中放置分隔符来做到这一点。第一个数字将是第一个分隔符之前的总和,第二个 - 分隔符之间的个数,第三个 - 其余的。请注意,因为我们允许数字为零,所以我们允许将分隔符放置在相同的间隙中,并且也可以放置在第一个 1 之前和最后一个 1 之后。这完全等同于“与重复总数 + 1 个元素的组合第二类”正如我已经说过的,是经典的组合问题。您可以阅读这些组合 here 但基本上答案将是 ((total + 1) * (total + 2)) / 2。顺便说一句,我建议至少用算法标签重新标记这个问题。

编辑:根据进一步解释的要求,我将用示例来说明我的所有想法(实际上与您在问题中给出的示例相同):我们需要将 2 分成三组。 2 导致我们必须写的数量:_1_1_。在这里,我用“_”写了所谓的空白。现在,我将用“|”表示两个分隔符。同样,分隔符用于确定 sum 分区中的第一个、第二个和第三个数字使用多少个 1。左边是我用我的符号写的组合,右边是你的符号对应的组合。

||_1_1_ -> 0, 0, 2
|_1|_1_ -> 0, 1, 1
|_1_1|_ -> 0, 2, 0
_1||_1_ -> 1, 0, 1
_1|_1|_ -> 1, 1, 0
_1_1||_ -> 2, 0, 0

现在,希望您能更好地理解什么是分隔符以及如何使用它们来确定组合中使用的三个数字是什么。如果你增加total,逻辑保持不变,但如果你需要说明情况,你需要写更多。

现在您可能也明白了为什么这些间隔是total + 1,以及这两个分隔符中的每一个如何碰巧出现在这两个间隔中。所有这些都使我们实现了与第二类 total + 1 元素重复的承诺组合。

【讨论】:

  • 你能用简单的英文写一下吗,或者你能进一步解释一下分隔符、空格等吗?
  • 好的,现在这有点帮助。我仍然完全不知道的部分是我将如何放入代码中。
  • 您的问题的答案是一行代码:printf("%d\n", ((total +1) * (total + 2)) / 2); 到目前为止,您对我的回答并不满意,这让我相信我误解了这个问题?
  • 这不是我要问的,我是问如何显示所有组合。喜欢 4
  • @TheMegalomaniac,“组合”这个词并不意味着你认为它的意思。你应该努力更清楚地解释实际规则。为什么说“004”是4的组合?是因为它们是总和为 4 的非负整数吗?您需要在问题中明确说明这一点。我建议您避免问题中的工作“组合”。
【解决方案3】:
#include <stdio.h>

void main()
{
    unsigned int num, p1, p2, p3, count=0;

    printf("Enter a positive number : ");

    scanf("%d", &num);

    for (p1=0; p1<=num; p1++)
    {
        for (p2=0; p2<=num; p2++)
        {
            for (p3=0; p3<=num; p3++)
            {
                if (p1 + p2 + p3 == num)
                {
                    count++;
                    printf("%d + %d + %d = %d\n", p1, p2, p3, num);
                }
            }
        }
    }
    printf("\nThe total combinations for your number %d = %d", num, count);
}

【讨论】:

    【解决方案4】:

    在我看来,这是数学不编程的问题

    如果所有三个整数都是不同的并且可以多次使用:

    3 possibilities for 1st digit
    3 possibilities for 2nd digit
    3 possibilities for 3rd digit
    --
    27 = 3*3*3
    

    【讨论】:

    • 显然,它必须显示所有组合。
    • 这是不正确的。每个列表的 sum 必须正好为 2。请参阅问题末尾的示例。示例中只有 6 个列表。 (但我必须承认,一开始我对这个问题感到困惑!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-01-16
    • 1970-01-01
    • 2020-08-24
    • 1970-01-01
    • 2018-11-20
    相关资源
    最近更新 更多