1. PAT乙级1087题解:利用集合特性统计不重复数值
这道PAT乙级1087题目看似简单,但蕴含着几个值得深入探讨的编程技巧。题目要求我们计算从1到n的所有整数i,经过i/2 + i/3 + i/5运算后,得到的不同结果的数量。下面我将从解题思路、代码实现到性能优化,全面解析这道题目。
1.1 题目核心逻辑分析
题目给出的计算公式是i/2 + i/3 + i/5,这里的除法是整数除法(即向下取整)。例如当i=6时:
- 6/2 = 3
- 6/3 = 2
- 6/5 = 1
- 总和为3+2+1=6
我们需要计算从1到n的所有i值经过这个运算后,得到的不同结果的总数。
1.2 集合数据结构的妙用
C++中的set容器是一个基于红黑树实现的有序集合,它有一个非常重要的特性:自动去重。这意味着无论我们向set中插入多少个相同的元素,它最终只会保留一个副本。这个特性正好完美契合本题的需求——我们需要统计不同结果的数量。
cpp复制set<int> s;
s.insert(1); // 集合变为{1}
s.insert(1); // 集合仍为{1}
s.insert(2); // 集合变为{1,2}
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 完整代码实现与逐行解析
让我们仔细分析给出的完整代码实现,理解每一行代码的作用和背后的思考。
2.1 代码结构解析
cpp复制#include<bits/stdc++.h>
using namespace std;
int main() {
int n;
cin >> n;
set<int> s;
for(int i = 1; i <= n; i ++)
s.insert(i/2 + i/3 + i/5);
cout << s.size() << endl;
return 0;
}
2.2 关键代码段详解
-
头文件包含:
cpp复制#include<bits/stdc++.h>这是一个万能头文件,包含了C++标准库中的所有头文件。在编程竞赛中常用,但在实际工程项目中不推荐使用,因为会增加编译时间。
-
输入处理:
cpp复制
