基础算法(二)( 枚举)

1.枚举算法介绍:

  • 枚举算法是一种基本的算法思想,它通过穷举所有可能的情况来解决问题。它的基本思想是将问题的解空间中的每个可能的解都枚举出来,并进行验证和比较,找到满足问题条件的最优解或者所有解。
  • 枚举算法适用于问题规模较小、解空间可穷举的情况。它的优点是简单直观,不需要复杂的数学推导,易于实现。但是,由于需要穷举所有可能的情况,对于问题规模较大的情况,枚举算法的时间复杂度可能会非常高,效率较低。

2.解空间的类型:

  • 解空间可以是一个范围内的所有数字(或二元组、字符串等数据),或者满足某个条件的所有数字。
  • 当然也可以是解空间树,一般可分为子集树和排列树,针对解空间树,需要使用回溯法进行枚举(在后面讲到搜索的时候会讲到)

目前仅使用循环去暴力枚举解空间,具体的解空间类型需要根据题目来理解构造。


3.循环枚举解空间:

1.首先确定解空间的维度,即问题中需要枚举的变量个数。

  • 例如:当题目要求的是满足条件的数字时,我们可以循环枚举某个范围内的数字。如果要求的是满足条件的二元组,我们可以用双重循环分别枚举第一个和第二个变量,从而构造出一个二元组。

2.对于每个变量 确定其可能的取值范围。这些范围可以根据问题的性质和约束条件来确定。这一步往往是时间复杂度优化的关键。

3.在循环体内,针对每个可能解进行处理。可以进行问题的验证、计算、输出等操作


4.例题讲解:

题号:lanqiao OJ 191 

1.特别数的和:

该题解空间:是1~n中所有的整数 

#include<bits/stdc++.h>
using namespace std;
bool f(int x){
  while(x){
    int y=x%10;
    if(y==2||y==0||y==1||y==9){
      return true;
    }
    x/=10;
  }
  return false;
}
int main(){
  int n;cin>>n;
  int ans=0;
  for(int i=1;i<=n;++i){
    if(f(i)){
      ans+=i;
    }
  }
  cout<<ans<<'\n';
  return 0;
}

题号:lanqiao OJ 152

2.反倍数:

该题解空间:也是1~n中所有的整数  

#include<bits/stdc++.h>
using namespace std;
int a,b,c;
bool f(int x){
  return x%a!=0&&x%b!=0&&x%c!=0;
}
int main(){
  int n;cin>>n;
  cin>>a>>b>>c;
  int ans=0;
  for(int i=1;i<=n;++i){
    if(f(i)){
      ans++;
    }
  }
  cout<<ans<<'\n';
  return 0;
}

 题号:lanqiao OJ 3227

3.找到最多的数

 使用map来存储该数字出现的次数

#include<bits/stdc++.h>
using namespace std;
map<int,int> mp;
int main(){
  int n,m;
  cin>>n>>m;
  for(int i=1;i<=m*n;++i){
    int x;cin>>x;
    mp[x]++;
  }
  for(const auto & [x,y] : mp){
    if(2*y>=n*m/2){
      cout<<x<<'\n';
    }
  }
  return 0;
}

 ###上述皆枚举所有数字(解空间),再加之判断是否满足条件

  • 12
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值