枚举
基于逐个尝试答案的一种问题求解策略。
1、例如:求小于N的最大素数
- 找不到一个数学公式,使得根据N就可以直接计算出这个最大素数。
- N-1是素数吗?
- N-2是素数吗?
- …
-> 判断N-i是否为素数的问题
-> 转化为求小于N的全部素数(可以用筛选法)
【C++实现】
#include <iostream>
#include <math.h>
using namespace std;
bool is_preNum(int Num) {
for (int i = 2; i <= sqrt(Num); i++){
if (Num%i == 0){
return false;
}
}
return true;
}
int main()
{
int N;
cout<< "Please Input a int Num(>=2):" << endl;
cin >> N;
if (N < 2) {
cout << "Error Num" << endl;
return 0;
}
for (int i = N - 1; i >=2; i--) {
if (is_preNum(i)) {
cout << "The max prenum is :" << i << endl;
break;
}
}
system("pause");
return 0;
}
2、“完美立方”
解题思路:
四重循环枚举a, b, c, d, 且a 在最外层,d 在最里层,每一层都是从小打到枚举,
- a 的枚举范围是A[2, N]
- b 的枚举范围是B[2, a-1 ]
- c 的枚举范围是C[b, a-1]
- d 的枚举范围是D[c, a-1]
合理的选取枚举范围,能减少不必要的运算。
#include <iostream>
#include <time.h>
using namespace std;
int main()
{
int N;
double start, stop;
start = clock();
std::cin >> N;
start = clock();
for (int a = 2; a <= N; ++a) { //枚举a∈[2,N]
for (int b = 2; b < a; ++b) { //对于每一个a,枚举b∈[2,a-1]
for (int c = b; c < a; ++c) { //对于每一个a和b,枚举c∈[b,a-1]
for (int d = c; d < a; ++d) { //对于每一个a\b\c,枚举d∈[c,a-1]
if (a*a*a == b * b*b + c * c*c + d * d*d) //若枚举出一组数据满足要求,则打印输出
std::cout << "Cude=" << a << '\t' << "Triple=" << b << '\t' << c << '\t' << d << endl;
}
}
}
}
stop = clock();
double duration = (stop - start) / CLK_TCK; //To calculate the time that this function used
std::cout << stop - start <<'\t'<<duration << endl;
system("pause"); //Check results
return 0;
}
3、“生理周期”