🧠 算法学习日记 | 今天我用「枚举」解了三道题,原来简单也能很优雅!
大家好,我是你们的算法学习搭子 👋
今天继续我的算法入门之旅,重点练习了**枚举(Brute Force)**这一基础但极其重要的方法。
很多人觉得"枚举=暴力=低效",但其实,在数据规模可控的情况下,枚举是最可靠、最直观的解题方式。更重要的是------它能帮你快速验证思路是否正确!
今天我完整做了三道题,每一道都坚持用最朴素的枚举方法解决。下面我把题目原文 和我的原始代码原封不动贴出来,不做任何删减或美化,只为真实记录学习过程。
🔹 题目一:特别数的和
题目描述
小明对数位中含有 2、0、1、9 的数字很感兴趣(不包括前导 0),在 1 到 40 中这样的数包括 1、2、9、10 至 32、39 和 40,共 28 个,他们的和是 574。
请问,在 1 到 n 中,所有这样的数的和是多少?
输入描述输入格式:
输入一行包含一个整数 n ((( 1 \\leq n \\leq 10\^4 )。
输出描述输出一行,包含一个整数,表示满足条件的数的和。
输入输出样例
输入
49
输出
574
运行限制
- 最大运行时间:1s
- 最大运行内存:256M
✅ 我的代码
cpp
#include <iostream>
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 sum=0;
for(int i=1;i<=n;i++){
if(f(i)){
sum+=i;
}
}
cout<<sum;
return 0;
}
🔹 题目二:反倍数
题目描述
给定三个整数 a, b, c ,如果一个整数既不是 a 的整数倍也不是 b 的整数倍还不 是 c 的整数倍,则这个数称为反倍数。
请问在 1 至 n 中有多少个反倍数。
输入描述输入的第一行包含一个整数 n 。
第二行包含三个整数 a, b, c ,相邻两个数之间用一个空格分隔。其中,,相邻两个数之间用一个空格分隔。 其中,,相邻两个数之间用一个空格分隔。其中, 1 \\leq n \\leq 1000000 ,,, 1 \\leq a \\leq n ,,, 1 \\leq b \\leq n ,,, 1 \\leq c \\leq n 。
输出描述输出一行包含一个整数,表示答案。
输入输出样例
输入
36
2 3 6
输出
10
样例说明 :
以下这些数满足要求:1, 5, 7, 11, 13, 17, 19, 23, 25, 29。
运行限制
- 最大运行时间:1s
- 最大运行内存:256M
✅ 我的代码
cpp
#include <iostream>
using namespace std;
int a,b,c;
bool f(int x){
if(x%a!=0 && x%b!=0 && x%c!=0)
return true;
else
return false;
}
int main()
{
int n;
cin>>n;
cin>>a>>b>>c;
int count=0;
for(int i=1;i<=n;i++){
if(f(i)){
count++;
}
}
cout<<count;
return 0;
}
🔹 题目三:找到最多的数
问题描述
在一个 n \\times m 的矩阵中,有一个数字出现了超过一半的次数,请设计一个高效算法找到这个数字。
输入格式输入第一行包含两个整数 n 和 m ,表示矩阵的大小(,表示矩阵的大小(,表示矩阵的大小( 1 \\leq n, m \\leq 10\^3 )。
接下来 n 行,每行包含 m 个正整数,表示矩阵中的元素。
输出格式输出一个整数,表示矩阵中出现次数超过一半的数字。
样例输入
3 3
1 2 3
2 2 2
1 2 2
样例输出
2
运行限制
| 语言 | 最大运行时间 | 最大运行内存 |
|---|---|---|
| C++ | 1s | 256M |
| C | 1s | 256M |
| Java | 2s | 256M |
| Python3 | 3s | 256M |
| PyPy3 | 3s | 256M |
| Go | 3s | 256M |
| JavaScript | 3s | 256M |
✅ 我的代码
cpp
#include <iostream>
#include <bits/stdc++.h>
using namespace std;
map<int,int> mp;
int main()
{
int m,n;
cin>>m>>n;
for(int i=1;i<=n*m;i++){
int a;
cin>>a;
mp[a]++;
}
for(const auto &i:mp){
if(2*i.second>n*m){
cout<<i.first;
}
}
return 0;
}
🌟 我的思考
这三道题,我全部使用了枚举的思想:
- 第一题:枚举每个数,判断其各位数字是否含有 2、0、1、9
- 第二题:枚举 1 到 n 的每个数,判断是否为 a、b、c 的非倍数
- 第三题:枚举每一个矩阵元素,统计频次后找出超过一半的数
虽然没有使用高级技巧(如数学公式、位运算、投票算法等),但枚举让我把问题拆解得非常清晰。只要逻辑正确,就能通过测试。
而且我发现:很多题目看似复杂,其实核心就是"遍历 + 判断"。当你能把枚举写对,就已经赢了一半。
✅ 总结
- 枚举不是"低端",而是"基础"
- 题目描述要读准,边界条件要抠细
- 代码可以简陋,但逻辑必须严谨
- 先求正确,再求高效
如果你也在刷算法题,不妨试试今天这三道题,用最直白的枚举方法做一遍。
有时候,慢一点,反而更快。
欢迎在评论区贴出你的解法,我们一起交流进步!👇