【C++算法基础】#2暴力枚举的方法论与优化技巧 - 大力出奇迹
暴力枚举法(Brute Force)是许多刚接触编程或算法的选手最容易上手,也最明显的算法。虽然暴力枚举往往效率极低,但是可以很快地解决一些问题。
本文将介绍暴力枚举法的方法和优化技巧。注意本文中许多名字并非专业学名,而是我自己定义的,请不要过于纠结。
🎈 作者:Eriktse
🎈 简介:19岁,211计算机在读,CCPC全国赛金牌,ICPC区域赛银牌退役选手🏆力争以通俗易懂的方式讲解编程和算法!❤️欢迎关注我,一起交流C++/Python算法。(优质好文持续更新中……)🚀
🎈欢迎加群一起玩耍~QQ群:600240150
1.确定解的形式(枚举变量)
在进行暴力之前,我们需要分析出解的形式,比如要求满足条件的三元组的个数,我们就枚举所有三元组,检查哪些满足条件。比如我们要求满足条件的区间的个数,就可以枚举所有的二元组(表示左右端点)。
有些题目解的形式可能不太唯一,需要选择合适的形式,对于不同的形式选择不同的枚举方法。比如枚举子集,可以用循环,也可以用dfs,有时候在能够剪枝的情况下,dfs会比循环直接枚举子集快很多。
2.选择枚举方法
常见的枚举方法有直接枚举法和递归枚举法,根据题目不同,有时候也可能有用一些构造方法来进行枚举。
常见的直接枚举(循环)不会超过4层循环,且循环层数固定。
如果你发现循环层数是可变的,往往就要用递归枚举,比如你要枚举所有长度小于等于
3.判断函数
在枚举出一个解后,我们需要判断其是否是可行解,于是我们要写一个判断函数。
这个判断函数可以根据你枚举出的一个解,来判断这个解是否可能。
举个例子
我们要求范围
那么我们解的形式就是一个整数,于是我们遍历解空间YES->将解加入到解集中,NO->舍弃
]。
例题
ETOJ 1014: straax'aks Array
链接:http://oj.eriktse.com/problem.php?id=1014
这道题看数据范围,明显支持
代码:
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
const ll N = 1e6 + 9, inf = 8e18;
ll a[N];
bool check(ll a, ll b, ll c, ll m)
{
return (a + b + c) * (a ^ b ^ c) >= m;
}
void solve()
{
int n, m;cin >> n >> m;
for(int i = 1;i <= n; ++ i)cin >> a[i];
ll ans = 0;
for(int i = 1;i <= n; ++ i)
for(int j = i + 1;j <= n; ++ j)
for(int k = j + 1;k <= n; ++ k)
if(check(a[i], a[j], a[k], m))
{
ans ++;
//cout << a[i] << ' ' << a[j] << ' ' << a[k] << '\n';
}
cout << ans << '\n';
}
signed main()
{
ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
int _ = 1;
while(_ --)solve();
return 0;
}
ETOJ 1016: 全排列
链接:http://cdn.oj.eriktse.com/problem.php?id=1016
暴力枚举,但是我们发现这次用循环来写其实不好写了,所以改用递归。
注意需要按照字典序升序来写。
代码:
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
const ll N = 20, inf = 8e18;
ll a[N];
bitset<N> vis;
void dfs(ll dep, ll n)
{
if(dep == n + 1)
{
for(ll i = 1;i <= n; ++ i)cout << a[i] << " \n"[i == n];
return;
}
for(ll i = 1;i <= n; ++ i)
{
if(vis[i])continue;
vis[i] = true;
a[dep] = i;
dfs(dep + 1, n);
vis[i] = false;
}
}
void solve()
{
ll n;cin >> n;
dfs(1, n);
}
signed main()
{
ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
int _ = 1;
while(_ --)solve();
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
· 25岁的心里话