c 8个硬币组合代码

时间:2017-04-20 22:09:18

标签: c loops for-loop combinations

我的代码应该计算总组合。使用这些硬币支付1-500美元之间的现金:1,2,5,10,20,50,100,200。但它不能正确计算。我做错了什么? 您可以假设输入正确,并且您只能使用循环和if语句。你可能不会使用递归。

int pr, a, b, c, d, e, f, g,h, poss = 0;
printf_s("What is the amount that you like to check? (or press '0' to exit)\n");
scanf_s("%d", &pr);

for (a = 0; a <= pr; a++)
{
    for (b = 0; b <= (pr/2); b++)
    {
        for (c = 0; c <= (pr /5); c++)
        {
            for (d = 0; d <= (pr /10); d++)
            {
                for (e = 0; e <= (pr /20); e++)
                {
                    for (f = 0; f <= (pr / 50); f++)
                    {
                        for (g = 0; g <= (pr / 100); g++)
                        {

                            for (h = 0; h <= (pr/200); h++)
                            {
                                if (1 * a + 2 * b + 4 * c + 10 * d + 20 * e + 40 * f + 100 * g + h * 200 == pr)

                                    poss += 1;

                            }
                        }
                    }
                }
            }
        }
   }printf_s("The number of possibilities is: %d.\n", poss);
}

3 个答案:

答案 0 :(得分:2)

输入5时会报告正确的perms数,但扩展代码会输出错误的值。因为这行

if (1 * a + 2 * b + 4 * c + 10 * d + 20 * e + 40 * f + 100 * g + h * 200 == pr)

有错误的面额。它应该是

if (1 * a + 2 * b + 5 * c + 10 * d + 20 * e + 50 * f + 100 * g + h * 200 == pr)

您还应该移动

printf_s("The number of possibilities is: %d.\n", poss);

在循环之外。

答案 1 :(得分:1)

您的最终Index:需要脱离循环

printf

答案 2 :(得分:1)

正如Weather Vane回答中所提到的,OP在内部条件中使用了一些错误的乘数(4和40而不是5和50)。

值得注意的是,即使采用这种强力方法,我们也可以通过避免在(方式过于嵌套的)循环内部进行不必要的计算并将这些循环的范围限制到较小的范围来节省一些CPU时间。 考虑以下重构:

#include <stdio.h>

int number_of_possibilities(int price)
{
    int poss = 0;
// It takes less time to consume the bigger pieces earlier    
    for ( 
// 'a' represent the sum of the values of 200$ pieces, not the number of 200$
// pieces, which is 'a / 200'           
          int a = 0; a <= price;
// add the value of a single 200$ piece to move forward
          a += 200 )
    {
      for ( int b = 0,
// 'dif_b' is what is left from the price, once the 200$ pieces are counted
                dif_b = price - a;
// we don't need to iterate from 0 to 'price', but only to what is left
            b <= dif_b; b += 100 )                
      {
// 'dif_c' is what is left once the 100$ and 200$ pieces counted so far are
// subctracted from the original price. The same holds for the inner loops     
        for ( int c = 0, dif_c = dif_b - b; c <= dif_c; c += 50 )
        {
          for ( int d = 0, dif_d = dif_c - c; d <= dif_d; d += 20 )
          {
            for ( int e = 0, dif_e = dif_d - d; e <= dif_e; e += 10 )
            {
              for ( int f = 0, dif_f = dif_e - e; f <= dif_f; f += 5 )
              {
                for ( int g = 0, dif_g = dif_f - f; g <= dif_g; g += 2 )
                {
// now that only the 1$ coins are left to consider, we can avoid another inner
// loop and just realize that we need exactly 'dif_g - g' 1$ coins to pay the 
// full price, so there is one and only one possible combination.
                  ++poss;
                }
              }
            }
          }
        }      
      }
    }
    return poss;
}


int main(void)
{
    printf("  i   number of possibilities\n\n");
    for ( int i = 0; i < 501; ++i )
    {
        printf("%4d %16d\n", i, number_of_possibilities(i));
    }
    return 0;
}

其中包含以下内容:

  i   number of possibilities

   0                1
   1                1
   2                2
   3                2
   4                3
   5                4
   6                5
   7                6
   8                7
   9                8
  10               11

 ...

  99             4366
 100             4563
 101             4710    

 ...

 498          6159618
 499          6224452
 500          6295434

在1.6 GHz的旧Atom N270上执行不到2秒......