提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
前言
一、穷举法
1.思想
在可能的解空间中穷举出每一个解,并对每一个解进行判断,从而选出答案。关键是划定解空间的范围一定要覆盖所有的解,解空间的是可以呗穷举的是有限的。
1.特点
牺牲时间获取问题的所有的解
优点:问题的解决,思想相对比较简单,容易实现可以获取所有的解,在解决的问题规模比较的小的时候这种方法是一种比较好的方法。
缺点:问题的规模一旦比较大时,所消耗的时间比较多。
二、举例
1.求出100以内的素数
思想:遍历出1-100以内所有的数,找出满足条件的数。
代码如下(示例):
//判断是否为素数
int is_prime(int n)
{
int i=0;
for(i = 2;i<n;++i)
{
if(n%i == 0)
{
return 0;
}
}
return 1;
}
//遍历
void get_prime(int begin,int end)
{
for(begin;begin<end;++begin)
{
if(is_prime(begin))
{
printf("%d ",begin);
}
}
return ;
}
int main(void)
{
printf("input range from num1 to num2\n");
int i,j=0;
scanf("%d",&i);
scanf("%d",&j);
get_prime(i,j);
return 0;
}
2.三色球问题
问题描述:一共有12球其中红色有3颗,黄色有3颗,绿色有6颗,其中任意拿出8颗球,求各种颜色球出现的组合。
问题分析:
是一种排列组合的问题,最简单的方法就是采用穷举的思想,例出所有解的可能,然后再找出其中满足条件的解。
从12球中拿出8个求,每种颜色的球被拿到的个数是:
红球 | 黄球 | 绿球 |
---|---|---|
0,1,2,3 | 0,1,2,3 | 2,3,4,5,6 |
其中可以发现绿球的个数不可能是0,1,因为拿到所有的黄球和红球之后还要那2个绿球。所以出现的颜色组合是4 * 4 * 5 =80种可能。但是在这80种出现的情况i种必须满足:红+黄+绿=8 的条件才是真正的答案
代码如下(示例):
#include <stdio.h>
int main(int argc, const char *argv[])
{
int red,yellow,green=0;
int cnt = 0;
printf("red yellow green\n");
for(red=0;red<=3;red++)
{
for(yellow=0;yellow<=3;++yellow)
{
for(green=2;green<=6;++green)
{
if(8 == (red+yellow+green) )
{
cnt++;
printf("%2d%2d%2d\n",red,yellow,green);
}
}
}
}
printf("the number of answer are %d\n",cnt);
return 0;
}
代码运行结果:
3.刘主席的借书方案
问题描述:刘主席现在一共有5本新书,要借给小韩、小花、小王三位同学,每人只能借一本书,请帮刘老板计算一下一共有多少借书方案。
问题分析:应用穷举思想,把所有的借书方案罗列一编,找出满足条件的方案即可。小韩可以借5本书种的任意一本,小花和小王也是一样,所以借书方案一共有5 * 5 * 5 = 125,再把三人种借同一本书的情况排除,剩下的借书方案就满足刘主席的需求了。
代码展示:
int main(int argc, const char *argv[])
{
int i,j,k=0;
int cnt =0;
for(i=0;i<5;++i)
{
for(j=0;j<5;++j)
{
for(k=0;k<5;++k)
{
if( i!=j && i!=k && i!=k)
{
cnt++;
printf("(%d,%d,%d)\t",i,j,k);
}
}
}
}
printf("cnt=%d\n",cnt);
return 0;
}
结果:
4.新郎新娘结婚问题
问题描述:有三个新郎A,B,C,三个新娘X,Y,Z,有一个人不知道他们之间结婚的问题,就像他们询问,A说他马上要跟C结婚了;X说她的未婚夫是C;C说他将和Z结婚。这人知道他们都在开玩笑,请你用编程的方式推理出来,他们到底跟谁结婚了。
问题分析:应用穷举的思想,将他们所有的结婚情况例举出来,再排除,AX,XC,CZ这三种组合情况.
剩下的就只有第4种情况
代码展示:
#include <stdio.h>
int match(int i,int j,int k,char wife[])
{
if(wife[i] == 'X')
{
return 0;
}
if(wife[k] == 'X')
{
return 0;
}
if(wife[k] == 'Z')
{
return 0;
}
return 1;
}
int main(int argc, const char *argv[])
{
char husband[3] = {'A','B','C'};
char wife[3] = {'X','Y','Z'};
int i,j,k = 0;
int cnt =0;
//A的结婚情况
for(i = 0;i < 3;++i)
{
//B的结婚情况
for(j=0;j<3;++j)
{
//C的结婚情况
for(k=0 ; k<3 ;++k)
{
//一个新娘只能有一个新郎
if(i!= j && j != k && i!=k)
{
//排除AX,CX,CZ三种情况
if(match(i,j,k,wife))
{
printf("husband A ------ wife %c\n",wife[i]);
printf("husband B ------ wife %c\n",wife[j]);
printf("husband C ------ wife %c\n",wife[k]);
}
}
}
}
}
return 0;
}
结果展示: