枚举算法
枚举法的本质就是从所有候选答案中去搜索正确的解,使用该算法需要满足两个条件
<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;
}


浙公网安备 33010602011771号