入门算法-穷举法(计算完全数和求解幂集问题)

mac2022-06-30  28

写在前面,关于穷举法的定义自行去Google,在我的理解就是暴力求解,把所有可能都推算出来,这对于自己没有其他策略和解题思路的情况下,可以使用穷举法,但是其弊端也是很明显的,相对于其他算法思想来说时间复杂度是极高的,所以慎用。

一、使用技术

蛮力法所赖的基本技术——扫描技术 基本的扫描技术——遍历 (1)集合的遍历:按集合中元素序号的顺序处理各元素 (2)线性表的遍历:以数组形式存储,按下标顺序处理 (3)树的遍历:对二叉树,包括前序、中序、后序和层序 (4)图的遍历:深度优先、广度优先

二、适用范围

(1)理论上,蛮力法可以解决可计算领域的各种问题。 (2)蛮力法经常用来解决一些较小规模的问题。 (3)对于某些问题,蛮力法可以产生一些合理的算法,他们具备一定实用价值,而且不受问题规模的限制。 (4)蛮力法可以作为某类问题时间性能的底限,作为衡量同样问题效率的基础算法。

三、求解过程

根据问题中的条件将可能的情况一一列举出来,逐一尝试从中找出满足问题条件的解。但有时列举的情况数目很大,则需要排除一些明显不合理的情况,以减少问题可能解规模。 用蛮力法解决问题,通常从两个方面进行算法设计: 1)找出枚举范围:分析问题所涉及的各种情况。 2)找出约束条件:分析问题的解需要满足的条件,并用逻辑表达式表示。

四、基本格式

五、例题

1、编写一个程序,输出2~1000之间的所有完全数。所谓完全数,是指这样的数,该数的各因子(除该数本身外)之和正好等于该数本身,例如:   6=1+2+3   28=1+2+4+7+14 解:先考虑对于一个整数m,如何判断它是否为完全数。从数学知识可知:一个数m的除该数本身外的所有因子都在1~m/2之间。算法中要取得因子之和,只要在1~m/2之间找到所有整除m的数,将其累加起来即可。如果累加和与m本身相等,则表示m是一个完全数,可以将m 输出。

// main.cpp // dome4 // // Created by ExiFeng on 2019/9/26. // Copyright © 2019 ExiFeng. All rights reserved. // #include <iostream> #include <cmath> using namespace std; 方法1 int main() { int i,j,n; cout<<"2-1000内的所有完数有:"; for(i=2; i<=1000; i++) { n=1; for(j=2; j<sqrt(i); j++) if(i%j==0) n+=(j+i/j); if(i==n) cout<<i<<" "; } cout<<endl; return 0; } //方法2 int main(){ int i,j,n; cout<<"2-1000内的所有完数有:"; for(i=2; i<=1000; i++) { n=1; for(j=2; j<=i/2; j++) if(i%j==0) n+=j; if(i==n) cout<<i<<" "; } cout<<endl; return 0; }

2、问题描述:对于给定的正整数n(n≥1),求1~n构成的集合的所有子集(幂集)。 幂集(Power Set):原集合中所有的子集(包括全集和空集)构成的集族 n为3时,集合为:{1, 2, 3} 所有的子集为:{}, {1}, {2}, {3}, {1,2}, {1,3}, {2,3}, {1,2,3} 总次数=2的n次方

void first(int b[],int n); int main(){ int n = 3; int a[3] = {1,2,3}; int b[3] = {0,0,0}; int i, k; int pw = pow(2, n); cout << "1—" << n << "的幂集" << endl; for (i = 0; i < pw; i++) { cout << "{"; for (k = 0; k < n; k++) if (b[k]) cout << a[k]; cout << "}"; first(b, n); } } void first(int b[],int n){ for (int i = 0; i < n; i++) { if(b[i]) b[i] = 0; else{ b[i] = 1; break; } } }

当然,求解幂问题还可以使用回溯法和动态规划法,在这里我仅此列举穷举法,有兴趣的同学们可以自行google。

最新回复(0)