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

结果展示

与上述结果一样


拓展 水仙花数

相关文章
|
4天前
|
算法
枚举算法:解决问题的穷举之道(二)
枚举算法:解决问题的穷举之道(二)
|
4天前
|
算法
枚举算法:解决问题的穷举之道(一)
枚举算法:解决问题的穷举之道(一)
|
10月前
|
存储 算法
1【百度之星】基础算法讲解—穷举、贪心(下)
1【百度之星】基础算法讲解—穷举、贪心(下)
|
算法
基础算法练习200题08、百鸡问题(循环+逻辑判断+穷举)
基础算法练习200题08、百鸡问题(循环+逻辑判断+穷举)
93 0
基础算法练习200题08、百鸡问题(循环+逻辑判断+穷举)
|
4天前
|
算法 数据安全/隐私保护 计算机视觉
基于二维CS-SCHT变换和LABS方法的水印嵌入和提取算法matlab仿真
该内容包括一个算法的运行展示和详细步骤,使用了MATLAB2022a。算法涉及水印嵌入和提取,利用LAB色彩空间可能用于隐藏水印。水印通过二维CS-SCHT变换、低频系数处理和特定解码策略来提取。代码段展示了水印置乱、图像处理(如噪声、旋转、剪切等攻击)以及水印的逆置乱和提取过程。最后,计算并保存了比特率,用于评估水印的稳健性。
|
1天前
|
算法
m基于BP译码算法的LDPC编译码matlab误码率仿真,对比不同的码长
MATLAB 2022a仿真实现了LDPC码的性能分析,展示了不同码长对纠错能力的影响。短码长LDPC码收敛快但纠错能力有限,长码长则提供更强纠错能力但易陷入局部最优。核心代码通过循环进行误码率仿真,根据EsN0计算误比特率,并保存不同码长(12-768)的结果数据。
19 9
m基于BP译码算法的LDPC编译码matlab误码率仿真,对比不同的码长
|
2天前
|
算法
MATLAB|【免费】融合正余弦和柯西变异的麻雀优化算法SCSSA-CNN-BiLSTM双向长短期记忆网络预测模型
这段内容介绍了一个使用改进的麻雀搜索算法优化CNN-BiLSTM模型进行多输入单输出预测的程序。程序通过融合正余弦和柯西变异提升算法性能,主要优化学习率、正则化参数及BiLSTM的隐层神经元数量。它利用一段简单的风速数据进行演示,对比了改进算法与粒子群、灰狼算法的优化效果。代码包括数据导入、预处理和模型构建部分,并展示了优化前后的效果。建议使用高版本MATLAB运行。
|
4天前
|
算法 计算机视觉
基于高斯混合模型的视频背景提取和人员跟踪算法matlab仿真
该内容是关于使用MATLAB2013B实现基于高斯混合模型(GMM)的视频背景提取和人员跟踪算法。算法通过GMM建立背景模型,新帧与模型比较,提取前景并进行人员跟踪。文章附有程序代码示例,展示从读取视频到结果显示的流程。最后,结果保存在Result.mat文件中。
|
4天前
|
资源调度 算法 块存储
m基于遗传优化的LDPC码OMS译码算法最优偏移参数计算和误码率matlab仿真
MATLAB2022a仿真实现了遗传优化的LDPC码OSD译码算法,通过自动搜索最佳偏移参数ΔΔ以提升纠错性能。该算法结合了低密度奇偶校验码和有序统计译码理论,利用遗传算法进行全局优化,避免手动调整,提高译码效率。核心程序包括编码、调制、AWGN信道模拟及软输入软输出译码等步骤,通过仿真曲线展示了不同SNR下的误码率性能。
9 1
|
4天前
|
存储 算法 数据可视化
基于harris角点和RANSAC算法的图像拼接matlab仿真
本文介绍了使用MATLAB2022a进行图像拼接的流程,涉及Harris角点检测和RANSAC算法。Harris角点检测寻找图像中局部曲率变化显著的点,RANSAC则用于排除噪声和异常点,找到最佳匹配。核心程序包括自定义的Harris角点计算函数,RANSAC参数设置,以及匹配点的可视化和仿射变换矩阵计算,最终生成全景图像。