穷举法在C\C++语言编程中的应用

穷举法在C\C++语言编程中的应用

在我们日常的编程生活中,我们往往需要将问题进行分析解决,我们可以用逻辑的方法对事情进行分析。

但有的时候如果将问题所有可能的答案一一列举,根据条件判断词答案是否合适,合适就保留,不合适就丢弃的这种方法,可以很好的解决我们生活中很多的问题,这种方法叫做枚举法,也叫做穷举法

那我们该如何运用这种方法分析问题,又该如何用这种思维解决编程上的困难呢?

首先,采用枚举算法解题的基本思路:
①确定枚举对象、枚举范围和判定条件;
②枚举可能的解,验证是否是问题的解。

在我们使用计算机进行编程的过程中,我们要清楚的认识计算机,最大的特点就是计算速度快,计算准确率高,那么我们用这种方式并可以发现枚举法对于计算机编程的极大好处,他可以确定对象与范围和判断条件来以此列举出所有的情况,我们也可以自己观察所枚举可能的所有解,自行验证是否为我们所求到的解。

我们可以举一个典型的例子:
"水仙花数 "是指一个三位数,其各位数字立方和等于该数本身。例如:153是一个 "水仙花数 ",因为153=1的三次方+5的三次方+3的三次方。

#include<stdio.h>
int main()
{
int a,b,x,y,z,i;
scanf("%d%d",&a,&b);
for(i=a;i<=b;i++)//(1):这是我们所要限定三位数的范围[a,b],即确定枚举对象、枚举范围

(1):这是我们所要限定三位数的范围[a,b],即确定枚举对象、枚举范围

{
x=i/100;
y=(i%100)/10;
z=i%10;   //(2): X是我们所要求的百位数,Y是我们所要求的十位数Z是我们求的个位数

(2): X是我们所要求的百位数,Y是我们所要求的十位数,Z是我们求的个位数

if(i==(x*x*x)+(y*y*y)+(z*z*z))//(3):这是我们的判定条件:其各位数字立方和等于该数本身
printf("%d ",i);
}
return 0;
}

(3):这是我们的判定条件:其各位数字立方和等于该数本身

我们利用“/,%”的方式得到各位,并用水仙花数的判别方法得到结果,那我们不妨试验一下:
我们假定三位数的范围为:[100,999]
即a=100,b=999

在这里插入图片描述

153 370 371 407就是我们所要的水仙花数

由于枚举法一般是现实生活中问题的“直译”,比较直观,易于理解;枚举法建立在考察大量状态、甚至是穷举所有状态的基础上,所以算法的正确性比较容易证明。但是解题的最大的缺点是运算量比较大,解题效率不高,如果枚举范围太大(一般以不超过两百万次为限),在时间上就难以承受。

因此我们发现按照问题本身的性质,采用循环结构举出该问题,所有可能的解在逐一列举的过程中,我们采用分支结构来判断是否为真正的解,以此达到,既不遗漏也不重复的优化结果。

循环结构的应用非常广泛,其中我国古代数学家张邱建在《算经》中出了一道“百钱买百鸡”的问题,题意是这样的:5文钱可以买一只公鸡,3文钱可以买一只母鸡,1文钱可以买3只雏鸡。现在用100文钱买100只鸡,那么各有公鸡、母鸡、雏鸡多少只

这类问题在数学上可以列三元一次方程组。但是我们可以发现只有两个式子,一个总价钱100文的式子,一个鸡总数的例子,属于线性相关条件,存在多种购买情况,那我们就可以用循环来解决。

第一种方法从不同种类鸡的个数得出for循环结构

#include<stdio.h>
int main()
{
int z=0;
for(int a=0;a<=20;a++)//公鸡不能超过20只
{
for(int b=0;b<=33;b++)//母鸡不能超过33只
{
for(int c=0;c<=100;c++)//雏鸡不能超过100只

根据分析:
100÷5=20 所以公鸡不超过20只
100÷3=33……1 所以母鸡不超过33只
100÷(1/3)=300 但是就能买100只鸡,所以雏鸡不超过100只

{					      if(a+b+c==100&&15*a+9*b+c==300)//满足共花100
{
z++;
printf("公鸡%d只母鸡%d只雏鸡%d只 ",a,b,c);
}
}
}
}
return 0;
}

根据所列的两组三元一次方程式,得到限定条件。

第二种方法从不同种鸡的不同价格得到for循环结构

int sum=0;
for(int a =0;5*a<=100;a++)//光买公鸡的价格不能超过100文
{
for(int b=0;3*b<100;b++)//光买母鸡的价格不能超过100文
{
for(int c=0;c<100;c++)//光买雏鸡的价格不能超过100文

其实如果将钱数右移,与计算鸡的个数范围一致,只不过更好理解

{ 
if(15*a+9*b+C==300&&a+b+c==100)
{
sum+=1;
printf("公鸡%d只母鸡%d只雏鸡%d只 ",a,b,c);
}

以上两种方法都可以得到一样的结果:
在这里插入图片描述
分析循环结构后,我们利用分支结构法解决特定的问题,例如100以内素数的判断

#include<stdio.h>
void main()
{
int i,j,flag=1;
for(j=2;j<=100;j++)
{
flag=1;
for(i=2;i<j;i++)
{
if(j%i==0)
{
flag=0;
break;
}
}

利用同样的for循环得到穷举的结果

printf("%d",j);
if(flag==1)
{
printf("素数\n");
}
else
{
printf("非素数\n");
}
}
}

分支结构依次判断是否为素数

最后得到的结果非常明朗:
在这里插入图片描述
通过以上的几种例题与方法分析,我们可以清晰的看到利用穷举法可以解决常见的应用问题,在数据量较小时,我们用循环结构与分支结构可以快速搞定。

我们从分析问题抽取数学模型导出解析表达式设计算法编写代码调试运行程序的步骤,用分析法解决问题,具有高效快捷的特点。

由此我们利用枚举法的
时间复杂度
采用状态总数考察单个状态
表示以此得到优化,从而
减少状态总数
降低单个状态的考察代价
同时我们可以从
提取有效信息减少重复计算
将原问题化为更小的问题
根据问题的性质进行截肢
引进其他算法等等方面进行考虑

以上就是我对枚举法相关应用及方法分析的具体解释,谢谢观看

https://baike.baidu.com/item/枚举法/2473707?fromtitle=%E7%A9%B7%E4%B8%BE%E6%B3%95&fromid=1431412&fr=aladdin

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值