枚举------坑爹的奥数
Posted guohaoblog
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了枚举------坑爹的奥数相关的知识,希望对你有一定的参考价值。
小哼在数学课上遇到一道奥数题是这样的,[][][]+[][][]=[][][],将数字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 }
运行结果如下:
以上是关于枚举------坑爹的奥数的主要内容,如果未能解决你的问题,请参考以下文章