枚举法的本质就是从所有候选答案中去搜索正确的解,使用该算法需要满足两个条件
<1>可预先确定候选答案的数量
<2>候选答案的范围在求解之前必须有一个确定的集合
例一,求解哪些数字的组合满足下图所示的格式
#include <stdio.h> int main(void){ int i1, i2, i3, i4, i5; long multi, result; for(i1=1; i1<=9; i1++){ for(i2=0; i2<=9; i2++){ for(i3=0; i3<=9; i3++){ for(i4=0; i4<=9; i4++){ for(i5=0; i5<=9; i5++){ multi = i1*10000+i2*1000+i3*100+i4*10+i5; result = i5*100000+i5*10000+i5*1000+i5*100+i5*10+i5; if(multi*i1 == result){ printf("\n%5d%2d%2d%2d%2d\n",i1,i2,i3,i4,i5); printf("X%12d\n",i1); printf("________________\n"); printf("%3d%2d%2d%2d%2d%2d\n",i5,i5,i5,i5,i5,i5); } } } } } } getch(); return 0; }
例二,在等号左边的数字之间填入加减乘除任意一个符号,使等式成立。
需要考虑的问题
<1>当填入除号的时候,右侧的数不能为0,这个可以用判断解决。
<2>乘除的运算级别比加减高。可以考虑设置两个变量,left保存运算符左边的值,right保存运算符右边的值。
#include <stdio.h> int main(void){ int j, i[5];//j是循环变量,数组i用来表示4个运算符+-*/,从i[1]到i[4],不使用i[0]了 int sign;//保存累加运算时候的符号 int result;//保存运算式的结果 int count = 0;//计数器,统计符合条件的方案 int num[6];//保存5个数字,从munber[1]到number[5] float left, right;//保存中间结果 char oper[5] = {' ','+','-','*','/'};//保存运算符,注意数组第一个元素两个单引号之间一定要有个空格 printf("请输入5个数字"); for(j=1; j<=5; j++){ scanf("%d",&num[j]); } printf("请输入结果:"); scanf("%d",&result); for(i[1]=1;i[1]<=4;i[1]++){//循环四种运算符,1表示加,2表示减,3表示乘,4表示除 if((i[1]<4) || (num[2]!=0) ){//不是除法,或者是除法后面的数字不为0,才能继续循环 for(i[2]=1;i[2]<=4;i[2]++){ if((i[2]<4) || (num[3]!=0) ){ for(i[3]=1;i[3]<=4;i[3]++){ if((i[3]<4) || (num[4]!=0) ){ for(i[4]=1;i[4]<=4;i[4]++){ if((i[4]<4) || (num[5]!=0) ){ left = 0;//初始时候left为0 right = num[1];//初始时right是第一个参与运算的数字 sign = 1;//初始符号为加号 for(j=1; j<=4; j++){ switch(oper[i[j]]){ case '+' : left = left + sign*right; sign = 1; right = num[j+1]; break; case '-' : left = left + sign*right; sign = -1; right = num[j+1]; break; case '*' : right = right*num[j+1]; break; case '/' : right = right/num[j+1]; break; } } if(left+sign*right==result){ count++; printf("%3d:",count); for(j=1; j<=4; j++){ printf("%d%c",num[j],oper[i[j]]); } printf("%d=%d\n",num[5],result); } } } } } } } } } if(count==0){ printf("没有符合要求的方法\n"); } getch(); return 0; }