1【百度之星】基础算法讲解—穷举、贪心(上)

简介: 1【百度之星】基础算法讲解—穷举、贪心(上)

穷举及其应用

穷举概述


穷举法又称列举法、枚举法,是蛮力策略的具体体现,是一种简单而直接地解决问题的方法。其基本思想是逐一列举问题所涉及的所有情形,并根据问题提出的条件检验哪些是问题的解,哪些应予排除。


1、穷举法又称列举法,其基本思想是逐--列举问题所涉及的所有情况。

2、穷举法常用于解决“是否存在”或“有多少种可能”等问题。

3、应用穷举法时应注意对问题所涉及的有限种情形须一--列举,既不能重复,又不能遗漏。

4、穷举通常应用循环结构来实现。在循环体中,应用选择结构实施判断筛选,求得所要求的解。

穷举法的框架就如下所示

接下来我们直接上例题


真分数升序排序算法设计


题目与解法思路


[例1 ]统计分母在区间[a, b]的最简真分数(分子小于分母,且分子分母无公因数)共有多少个,并求最简真分数升序序列中的第k项(正整数a, b, k从键盘输入)。

算法设计:
➢为排序方便,设置数组arr2存储分子,数组arr1存储分母。真分数升序排序后的
第k项为arr2[n]/arr1[n]。
➢在[a, b]内穷举分数j/i的分母i: a,a+1,.,b;
➢对每一个分母i穷举分子j: 1,2, ..j-1。
➢若分子j与分母i存在大于1的公因数,说明i/ j非最简,忽略不计;否则赋
值得一个最简真分数arr2[n]/arr1[n]。数组下标n统计最简真分数的个数。应用冒
泡法排序后即可打印出指定的第n项arr2[n-1]/arr1[n-1]。


代码实现


分母遍历模块


1. for (i = a; i < b; i++)
2.  {
3.    int j = 0;
4.    for (j = 1; j < i; j++)
5.    {
6.      int c = gongyinshu(i, j);
7.      if (c)
8.      {
9.        arr1[n] = i;
10.         arr2[n++] = j;
11.       }
12.     }
13.   }

gongyinshu()函数实现


若无公因数,则返回1,if语句判断成功,将分母i放入arr1中,分子放入arr2中

1. int gongyinshu(int m, int n)
2. {
3.  int i = 0;
4.  for (i = 2; i < n; i++)
5.  {
6.    if (m % i == 0 && n % i == 0)
7.    {
8.      return 0;
9.    }
10.   }
11.   return 1;

冒泡排序实现升序

利用分数的比较方式进行比较后,分子与分母分别进行交换

1. for (i = 0; i < n; i++)
2.  {
3.    int j = 0;
4.    for (j = 0; j < n - 1 - i; j++)
5.    {
6.      if (arr1[j] * arr2[j + 1] < arr1[j + 1] * arr2[j])
7.      {
8.        int x = 0;
9.        int y = 0;
10.         x = arr1[j];//分母交换
11.         arr1[j] = arr1[j + 1];
12.         arr1[j + 1] = x;
13.         y = arr2[j];//分子交换
14.         arr2[j] = arr2[j + 1];
15.         arr2[j + 1] = y;
16.       }
17.     }
18.   }

进行输出

printf("第%d项为%d/%d", k, arr2[k - 1], arr1[k - 1]);

完整代码


1. #include <stdio.h>
2. 
3. int gongyinshu(int m, int n)
4. {
5.  int i = 0;
6.  for (i = 2; i < n; i++)
7.  {
8.    if (m % i == 0 && n % i == 0)
9.    {
10.       return 0;
11.     }
12.   }
13.   return 1;
14. }
15. 
16. 
17. int main()
18. {
19.   int a = 0;
20.   int b = 0;
21.   int i = 0;
22.   int n = 0;
23.   int k = 0;
24.   int arr1[100] = { 0 };
25.   int arr2[100] = { 0 };
26.   printf("请输入区间->");
27.   scanf("%d%d", &a, &b);
28.   printf("请输入你要查询的序列->");
29.   scanf("%d", &k);
30.   for (i = a; i < b; i++)
31.   {
32.     int j = 0;
33.     for (j = 1; j < i; j++)
34.     {
35.       int c = gongyinshu(i, j);
36.       if (c)
37.       {
38.         arr1[n] = i;
39.         arr2[n++] = j;
40.       }
41.     }
42.   }
43.   for (i = 0; i < n; i++)
44.   {
45.     int j = 0;
46.     for (j = 0; j < n - 1 - i; j++)
47.     {
48.       if (arr1[j] * arr2[j + 1] < arr1[j + 1] * arr2[j])
49.       {
50.         int x = 0;
51.         int y = 0;
52.         x = arr1[j];
53.         arr1[j] = arr1[j + 1];
54.         arr1[j + 1] = x;
55.         y = arr2[j];
56.         arr2[j] = arr2[j + 1];
57.         arr2[j + 1] = y;
58.       }
59.     }
60.   }
61.   printf("第%d项为%d/%d", k, arr2[k - 1], arr1[k - 1]);
62.   return 0;
63. }


求解集合A元素的序列


题目与解法思路


[例2]
己知集合A定义如下:1∈A,2∈A; x, y∈A => 2x+3y∈A试求集合A元素从小到大排列的序列的前n项。


➢x, y可以是己产生的所有已有项中的任意两项,己产生项越多,递推生成

的新项也就越多。

➢穷 举循环变量k从3开始递增1取值,到第n项时k的终值尚无法确定,可约

定一个较大的终值(例如10000)。

➢若k可由己有的项j,i推得, 即若k满足条件

k=2*j +3*i或k=2*i+3*j, 说明k是a数列中的一-项,输出就好

➢当项 数t达到规定项数n时,则退出穷举。


代码实现


此题简单,就不分模块进行介绍了,代码与注释如下

1. #include<stdio.h>
2. 
3. int main()
4. {
5.  int n = 0;
6.  int k = 0;
7.  int t = 0;
8.  printf("请输入->");
9.  scanf("%d", &n);
10.   for (k = 3; k < 10000; k++)
11.   {
12.     int i = 0;
13.     for (i = 2; i < k; i++)
14.     {
15.       int j = 0;
16.       for (j = 1; j < i - 1; j++)
17.       {
18.         int coun = 0;//每找到一个后coun都会变为1,所以这里需要重新赋值
19.         if (2 * i + 3 * j == k || 2 * i + 3 * j == k)
20.         {
21.           if (2 * i + 3 * j == k)
22.             printf("第%d项为:2*%d+3*%d=%d\n", t+1, i, j, k);
23.           else printf("第%d项为:2*%d+3*%d=%d\n", t+1, j, i, k);
24.           coun++;//跳出条件
25.           t++;//项数加一
26.         }
27.         if (coun == 1)//这层循环由于i已经确定,所以找到一个j时,便可以跳出
28.           break;
29.       }
30.       if (t == n)//判断是否达到n项,跳出循环
31.         break;
32.     }
33.     if (t == n)//判断是否达到n项,跳出循环
34.       break;
35.   }
36.   return 0;
37. }

运行结果展示


六位数穷举法的实现


■[例3]把一个6位整数分为前后两个3位数,若该数等于所分两个3位数和的平方,则称该数为6位分段和平方数。试求出所有6位分段和平方数。


方法一 对六位数穷举


实现方法:

对六位数进行遍历,首先这个六位数可以开平方,并且开平方后所得数为这个六位数前三位与后三位相加即可

代码实现

1. #include<stdio.h>
2. #include<math.h>
3. 
4. int main()
5. {
6.  int i = 0;
7.  for (i = 100000; i < 1000000; i++)
8.  {
9.    int b = sqrt(i);//开平方·
10.     if (b * b == i)//判断是否可以开平方
11.     {
12.       int q = i / 1000;//前三位
13.       int h = i % 1000;//后三位
14.       if (q + h == b)
15.       {
16.         printf("%d ", i);
17.       }
18.     }
19.   }
20.   return 0;
21. }

结果展示


方法二 对三位数进行穷举


实现方法:

用双层循环对所有三位数进行遍历

i代表前三位,j代表后三位

满足条件:(i+j)^2=i*1000+j,且i * 1000 + j<1000000

即可输出此六位数i*1000+j

代码实现

1. 
2. int main()
3. {
4.  int i = 0;
5.  int j = 0;
6.  for (i = 100; i < 10000; i++)
7.  {
8.    for (j = 0; j < 10000; j++)
9.    {
10.       if ((i + j) * (i + j) ==(i * 1000 + j)&& i * 1000 + j<1000000)
11.         printf("%d ", (i * 1000 + j));
12.     }
13.   }
14.   return 0;
15. }

结果展示

与上述结果一样


拓展 水仙花数

相关文章
|
7月前
|
算法
【软件设计师】常见的算法设计方法——穷举搜索法
【软件设计师】常见的算法设计方法——穷举搜索法
|
7月前
|
算法
枚举算法:解决问题的穷举之道(二)
枚举算法:解决问题的穷举之道(二)
|
7月前
|
算法
枚举算法:解决问题的穷举之道(一)
枚举算法:解决问题的穷举之道(一)
|
存储 算法
1【百度之星】基础算法讲解—穷举、贪心(下)
1【百度之星】基础算法讲解—穷举、贪心(下)
|
算法
基础算法练习200题08、百鸡问题(循环+逻辑判断+穷举)
基础算法练习200题08、百鸡问题(循环+逻辑判断+穷举)
133 0
基础算法练习200题08、百鸡问题(循环+逻辑判断+穷举)
|
19天前
|
算法
基于WOA算法的SVDD参数寻优matlab仿真
该程序利用鲸鱼优化算法(WOA)对支持向量数据描述(SVDD)模型的参数进行优化,以提高数据分类的准确性。通过MATLAB2022A实现,展示了不同信噪比(SNR)下模型的分类误差。WOA通过模拟鲸鱼捕食行为,动态调整SVDD参数,如惩罚因子C和核函数参数γ,以寻找最优参数组合,增强模型的鲁棒性和泛化能力。
|
25天前
|
机器学习/深度学习 算法 Serverless
基于WOA-SVM的乳腺癌数据分类识别算法matlab仿真,对比BP神经网络和SVM
本项目利用鲸鱼优化算法(WOA)优化支持向量机(SVM)参数,针对乳腺癌早期诊断问题,通过MATLAB 2022a实现。核心代码包括参数初始化、目标函数计算、位置更新等步骤,并附有详细中文注释及操作视频。实验结果显示,WOA-SVM在提高分类精度和泛化能力方面表现出色,为乳腺癌的早期诊断提供了有效的技术支持。
|
5天前
|
供应链 算法 调度
排队算法的matlab仿真,带GUI界面
该程序使用MATLAB 2022A版本实现排队算法的仿真,并带有GUI界面。程序支持单队列单服务台、单队列多服务台和多队列多服务台三种排队方式。核心函数`func_mms2`通过模拟到达时间和服务时间,计算阻塞率和利用率。排队论研究系统中顾客和服务台的交互行为,广泛应用于通信网络、生产调度和服务行业等领域,旨在优化系统性能,减少等待时间,提高资源利用率。
|
13天前
|
存储 算法
基于HMM隐马尔可夫模型的金融数据预测算法matlab仿真
本项目基于HMM模型实现金融数据预测,包括模型训练与预测两部分。在MATLAB2022A上运行,通过计算状态转移和观测概率预测未来值,并绘制了预测值、真实值及预测误差的对比图。HMM模型适用于金融市场的时间序列分析,能够有效捕捉隐藏状态及其转换规律,为金融预测提供有力工具。
|
21天前
|
算法
基于GA遗传算法的PID控制器参数优化matlab建模与仿真
本项目基于遗传算法(GA)优化PID控制器参数,通过空间状态方程构建控制对象,自定义GA的选择、交叉、变异过程,以提高PID控制性能。与使用通用GA工具箱相比,此方法更灵活、针对性强。MATLAB2022A环境下测试,展示了GA优化前后PID控制效果的显著差异。核心代码实现了遗传算法的迭代优化过程,最终通过适应度函数评估并选择了最优PID参数,显著提升了系统响应速度和稳定性。