1.枚举算法介绍
枚举算法是一种基本的算法思想,它通过穷举所有可能的情况来解决问题。
它的基本思想是将问题的解空间中的每个可能的解都枚举出来,并进行验证和比较,找到满足问题条件的最优解或者所有解。
枚举算法适用于问题规模较小、解空间可穷举的情况。
它的优点是简单直观,不需要复杂的数学推导,易于实现。但是,由于需要穷举所有可能的情况,对于问题规模较大的情况,枚举算法的时间复杂度可能会非常高,效率较低。
2.解空间的类型
解空间可以是一个范围内的所有数字(或二元组、字符串等数据)或者满足某个条件的所有数字。
当然也可以是解空间树,一般可分为子集树和排列树,针对解空间树,需要使用回溯法进行枚举(在后面讲到搜索的时候会讲到)。
我们目前仅使用循环去暴力枚举解空间,具体的解空间类型需要根据题目来理解构造。
3.循环枚举解空间
1.首先确定解空间的维度,即问题中需要枚举的变量个数例如当题目要求的是满足条件的数字时,我们可以循环枚举某个范围内的数字。如果要求的是满足条件的二元组,我们可以用双重循环分别枚举第一个和第二个变量,从而构造出一个二元组。
2.对于每个变量,确定其可能的取值范围。这些范围可以根据问题的性质和约束条件来确定。这一步往往是时间复杂度优化的关键。
3.在循环体内,针对每个可能解进行处理。可以进行问题的验证、计算、输出等操作
题目1:191
#include <bits/stdc++.h>
using namespace std;
bool f(int x){
int y;
while(x){
y = x % 10;//先筛选个位
if(y == 2 || y == 0 || y == 1 || y == 9){
return true;
}
x = x /10;
}
return false;
}
int main()
{
int ans = 0;
int n ;cin >> n;
for(int i = 1;i <= n ; ++i){
if(f(i)){
ans += i;
}
}
cout << ans << endl;
return 0;
}
题目2:152
#include <bits/stdc++.h>
using namespace std;
int a,b,c;
bool f(int x){
if(x % a !=0 && x % b != 0 && x % c !=0 ){
return true;
}
return false;
}
int main()
{
ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
int n;cin >> n;
int num = 0;
cin >> a >> b >> c;
for(int i = 1;i <= n ;++i){
if(f(i)){
num++;
}
}
cout << num << endl;
return 0;
}
题目3:3227
#include <bits/stdc++.h>
using namespace std;
map<int,int>mp;
int main()
{
ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
int n , m;
cin >> n >> m;
for(int i = 0; i < n*m ; ++i){
int x;cin>>x;
mp[x] ++;
}
for(auto &[x,y] : mp){
if(2 * y > n * m){
cout << x << endl;
}
}
return 0;
}
题目5:
#include <bits/stdc++.h>
using namespace std;
map <int ,int >mp;
int main(){
ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
int t;cin >> t;
int n,k,sum,day;
for(int i= 0 ; i < t ; ++i){
cin << n << k ;
for(int j = 0;j < n;++j){
int x;cin >> x;
mp[x]++;
}
day = (n - max(mp[x])) / k;
cout << day << endl;
mp.clear();
}
return 0;
}