枚举算法

 

枚举法的本质就是从所有候选答案中去搜索正确的解,使用该算法需要满足两个条件

<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;
}

 

posted @ 2016-10-13 10:11  建彬  阅读(1478)  评论(0编辑  收藏  举报