枚举------坑爹的奥数

小哼在数学课上遇到一道奥数题是这样的,[][][]+[][][]=[][][],将数字1~9分别填入9个[]中,每个数字只能使用一次使得等式成立。例如 173+286=459就是一个和合理的组合,请问一共有多少合理的组合呢? 注意:173+286=459与286+173=459是同一种组合!

方法一:枚举法(穷举法)

 1 #include <stdio.h>
 2 
 3 /*
 4   有9个方格 三个一组构成一个数字,两个数相加等于第三个数,这9个数从1~9中选取
 5   且每个数字只能使用一次使得等式成立  例如 173+286=459   
 6   请问一种有多少中合理的组合? 
 7 */ 
 8 
 9 int main(int argc, char *argv[])
10 {
11     int a[10],i,total=0;   // a[1]~a[9] 表示这9个数 
12     for(a[1]=1;a[1]<=9;++a[1])  // 第一个数的百位
13     for(a[2]=1;a[2]<=9;++a[2])  // 第一个数的十位 
14     for(a[3]=1;a[3]<=9;++a[3])  // 第一个数的个位
15     for(a[4]=1;a[4]<=9;++a[4])  // 第二个数的百位
16     for(a[5]=1;a[5]<=9;++a[5])  // 第二个数的十位
17     for(a[6]=1;a[6]<=9;++a[6])  // 第二个数的个位
18     for(a[7]=1;a[7]<=9;++a[7])  // 第三个数的百位
19     for(a[8]=1;a[8]<=9;++a[8])  // 第三个数的十位
20     for(a[9]=1;a[9]<=9;++a[9])  // 第三个数的个位
21     {   // 接下来判断每一位上的数互不相等
22         if(a[1]!=a[2] && a[1]!=a[3] && a[1]!=a[4] && a[1]!=a[5] && a[1]!=a[6] && a[1]!=a[7] && a[1]!=a[8] && a[1]!=a[9]
23                       && a[2]!=a[3] && a[2]!=a[4] && a[2]!=a[5] && a[2]!=a[6] && a[2]!=a[7] && a[2]!=a[8] && a[2]!=a[9]
24                                     && a[3]!=a[4] && a[3]!=a[5] && a[3]!=a[6] && a[3]!=a[7] && a[3]!=a[8] && a[3]!=a[9]
25                                                   && a[4]!=a[5] && a[4]!=a[6] && a[4]!=a[7] && a[4]!=a[8] && a[4]!=a[9]
26                                                                 && a[5]!=a[6] && a[5]!=a[7] && a[5]!=a[8] && a[5]!=a[9]
27                                                                                && a[6]!=a[7] && a[6]!=a[8] && a[6]!=a[9]
28                                                                                                && a[7]!=a[8] && a[7]!=a[9]                                                                                                         && a[8]!=a[9]
29             
30             && a[1]*100+a[2]*10+a[3] + a[4]*100+a[5]*10+a[6] == a[7]*100+a[8]*10+a[9] )
31             {
32                 total++;
33                 printf("%d%d%d+%d%d%d=%d%d%d
",a[1],a[2],a[3],a[4],a[5],a[6],a[7],a[8],a[9]);
34             }     
35     } 
36     
37     printf("
total=%d

",total/2);   // 因为输出的有重复的 比如 173+286=459 与 286+173=459是一样的 
38     return 0;
39 }

方法二:标记book[]数组,用来标记互不相等的数,代码如下:

 1 #include <stdio.h>
 2 int main(int argc, char *argv[])
 3 {
 4     //  算法改进  用book来标记互不相等的数
 5     int a[10],i,total=0,book[10],sum;
 6     for(a[1]=1;a[1]<=9;++a[1])  // 第一个数的百位
 7     for(a[2]=1;a[2]<=9;++a[2])  // 第一个数的十位 
 8     for(a[3]=1;a[3]<=9;++a[3])  // 第一个数的个位
 9     for(a[4]=1;a[4]<=9;++a[4])  // 第二个数的百位
10     for(a[5]=1;a[5]<=9;++a[5])  // 第二个数的十位
11     for(a[6]=1;a[6]<=9;++a[6])  // 第二个数的个位
12     for(a[7]=1;a[7]<=9;++a[7])  // 第三个数的百位
13     for(a[8]=1;a[8]<=9;++a[8])  // 第三个数的十位
14     for(a[9]=1;a[9]<=9;++a[9])  // 第三个数的个位
15     {
16         for(i=1;i<10;++i)   // 初始化book数组
17             book[i]=0;
18         for(i=1;i<10;++i)   // 如果某个数出现过就标记一下 
19             book[a[i]]=1;     
20             
21         // 统计共出现了多少个不同的数
22         sum = 0;
23         for(i=1;i<10;++i)
24             sum+=book[i];
25         // 如果正好出现了9个不同的数,并且满足等式条件,则输出
26         if(sum == 9 &&  a[1]*100+a[2]*10+a[3] + a[4]*100+a[5]*10+a[6] == a[7]*100+a[8]*10+a[9])
27         {
28             total++;
29             printf("%d%d%d+%d%d%d=%d%d%d
",a[1],a[2],a[3],a[4],a[5],a[6],a[7],a[8],a[9]);
30         }        
31     } 
32      
33     printf("
total=%d

",total/2); 
34     return 0;
35 }

运行结果如下:

原文地址:https://www.cnblogs.com/guohaoblog/p/9255706.html