正文

算法设计之枚举法(3)2007-09-20 08:40:00

【评论】 【打印】 【字体: 】 本文链接:http://blog.pfan.cn/goal00001111/29538.html

分享到:

练习: 1.元旦义卖:总共带50件商品,有两种构成,钥匙扣2块一个,漫画书4块一本,要卖出160块要如和搭配?   2.构造一个3*3的魔方:把数字1-9添入如图的表格中 2 7 6 9 5 1 4 3 8 要求每横,竖,斜列之和均相等(如图是一种情况)。输出所有可能的魔方。   3. 虫食算: 所谓虫食算,就是原先的算式中有一部分被虫子啃掉了,需要我们根据剩下的数字来判定被啃掉的字母。来看一个简单的例子: 43#9865#045 + 8468#6633 ____________ 44445509678 其中#号代表被虫子啃掉的数字。根据算式,我们很容易判断:第一行的两个数字分别是5和3,第二行的数字是5。 现在,我们对问题做两个限制: 首先,我们只考虑10进制加法的虫食算。 其次,虫子把所有的数都啃光了,我们只知道哪些数字是相同的,我们将相同的数字用相同的字母表示,不同的数字用不同的字母表示。 给定等式  A B C D E               D F G         +     D F G        ───────           X Y Z D E 其中每个字母代表一个数字,且不同数字对应不同字母。编程求出这些数字并且打出这个数字的算术计算竖式。     参考答案: 1.#include<stdio.h>   const int KEYPRICE = 2; //一个钥匙扣的价格 const int BOOKPRICE = 4;  //一本漫画书的价格   void Print(int money, int res);//计算并输出两种物品的数量各是多少   int main() {     int money = 160;//钱的总数     int res = 50;//物品的总数         Print(money, res);//计算并输出两种物品的数量各是多少         getchar();     return 0;       }   void Print(int money, int res) {     int maxKey = money / KEYPRICE;               int key, book;        for (key=0; key<maxKey; ++key)//枚举钥匙扣的可能数量     {         book = res - key;//漫画书的数量根据约束条件求得         if (key*KEYPRICE + book*BOOKPRICE == money)//约束条件         {             printf("key = %d, book = %d\n", key, book);         }     } }   2.参考程序一:九重循环,不做任何剪枝。 #include<stdio.h> #include<stdlib.h>   int Different(int a[], int len);   int main() {     int a[9] = {0};     int i;         for (a[0]=1; a[0]<=9; a[0]++)     for (a[1]=1; a[1]<=9; a[1]++)     for (a[2]=1; a[2]<=9; a[2]++)     for (a[3]=1; a[3]<=9; a[3]++)     for (a[4]=1; a[4]<=9; a[4]++)     for (a[5]=1; a[5]<=9; a[5]++)     for (a[6]=1; a[6]<=9; a[6]++)     for (a[7]=1; a[7]<=9; a[7]++)     {         if (Different(a, 8))         {             a[8] = 45-a[0]-a[1]-a[2]-a[3]-a[4]-a[5]-a[6]-a[7];             if ((a[0]+a[1]+a[2]) == (a[3]+a[4]+a[5]) && (a[0]+a[1]+a[2]) == (a[6]+a[7]+a[8])              && (a[0]+a[3]+a[6]) == (a[1]+a[4]+a[7]) && (a[0]+a[3]+a[6]) == (a[2]+a[5]+a[8])              && (a[0]+a[1]+a[2]) == (a[0]+a[4]+a[8]) && (a[0]+a[1]+a[2]) == (a[2]+a[4]+a[6]))             {                 for (i=0; i<9; i++)                 {                     printf("%5d", a[i]);                     if ((i+1)%3 == 0)                         printf("\n");                 }                 printf("\n\n");             }         }     }         system("pause");     return 0;       }   int Different(int a[], int len) {     int i, j;     for (i=0; i<len-1; i++)     {         for (j=i+1; j<len; j++)         {             if (a[i] == a[j])                 return 0;         }     }        return 1; }   参考程序二:八重循环,对每重循环均进行剪枝。 #include<stdio.h> #include<stdlib.h>   int IsElement(int a[], int len, int x);   int main() {     int a[9] = {0};     int i;         for (a[0]=1; a[0]<=9; a[0]++)     for (a[1]=1; a[1]<=9; a[1]++)     {     if (IsElement(a, 1, a[1]))     {     for (a[2]=1; a[2]<=9; a[2]++)     {     if (IsElement(a, 2, a[2]))     {     for (a[3]=1; a[3]<=9; a[3]++)     {     if (IsElement(a, 3, a[3]))     {     for (a[4]=1; a[4]<=9; a[4]++)     {     if (IsElement(a, 4, a[4]))     {     for (a[5]=1; a[5]<=9; a[5]++)     {     if (IsElement(a, 5, a[5]))     {     for (a[6]=1; a[6]<=9; a[6]++)     {     if (IsElement(a, 6, a[6]))     {     for (a[7]=1; a[7]<=9; a[7]++)     {     if (IsElement(a, 7, a[7]))     {     a[8] = 45-a[0]-a[1]-a[2]-a[3]-a[4]-a[5]-a[6]-a[7];     if ((a[0]+a[1]+a[2]) == (a[3]+a[4]+a[5]) && (a[0]+a[1]+a[2]) == (a[6]+a[7]+a[8])      && (a[0]+a[3]+a[6]) == (a[1]+a[4]+a[7]) && (a[0]+a[3]+a[6]) == (a[2]+a[5]+a[8])      && (a[0]+a[1]+a[2]) == (a[0]+a[4]+a[8]) && (a[0]+a[1]+a[2]) == (a[2]+a[4]+a[6]))     {         for (i=0; i<9; i++)         {             printf("%5d", a[i]);             if ((i+1)%3 == 0)                 printf("\n");         }         printf("\n\n");     }     }     }     }     }     }     }     }     }     }     }     }     }     }     }     system("pause");     return 0;       }   int IsElement(int a[], int len, int x) {     int i;     for (i=0; i<len; i++)     {         if (a[i] == x)             return 0;     }        return 1; }   3.算法分析:先看最高位和次高位, A, B都是和进位相加,又C+D+D的进位(设为j)不可能大于2,B+j的进位不能大于1,所以B = 9; Y = 1; X = A + 1; E+G+G的个位数字仍为E,说明G=0或G=5;同理 F=0或F=5; 做了这些简单的判断以后,可以大大提高穷举的效率。 #include<stdio.h>   int main() {        int A, B, C, D, E, F, G, X, Y, Z;        int m, n, sum;               B = 9;        Y = 1;        for (G=0; G<6; G+=5)               for (F=0; F<6; F+=5)               if (F!=G)                      for (A=2; A<9; A++)                      if (A!=G && A!=F)                             for (C=2; C<9; C++)                             if (C!=A && C!=G && C!=F)                                    for (D=2; D<9; D++)                                    if (D!=A && D!=C && D!=G && D!=F)                                           for (E=2; E<9; E++)                                           if (E!=A && E!=C && E!=D && E!=G && E!=F)                                           {                                                  X = A + 1;                                                  if (B!=X && C!=X && D!=X && E!=X && F!=X && G!=X)                                                  {                                                         Z = 45 - A - B - C - D - E - F - G - X - Y;                                                                                                                 m = A*10000 + B*1000 + C*100 + D*10 + E;                                                         n = D*100 + F*10 + G;                                                         sum = X*10000 + Y*1000 + Z*100 + D*10 + E;                                                                                                                        if (m + n * 2 == sum)                                                         {                                                                printf(" %d%d%d%d%d\n", A, B, C, D, E);                                                       printf("   %d%d%d\n", D, F, G);                                                       printf("+  %d%d%d\n", D, F, G);                                                       printf("_____________\n");                                                       printf(" %d%d%d%d%d\n", X, Y, Z, D, E);                                                       printf("\n");                                                         }                                                      }                                           }        getchar();        return 0; }

阅读(2687) | 评论(0)


版权声明:编程爱好者网站为此博客服务提供商,如本文牵涉到版权问题,编程爱好者网站不承担相关责任,如有版权问题请直接与本文作者联系解决。谢谢!

评论

暂无评论
您需要登录后才能评论,请 登录 或者 注册