#19248. 亚马逊雨林的物种普查
亚马逊雨林的物种普查
你好,我是阿西莫夫。
在生态学(Ecology)的研究中,有两个非常容易混淆的概念:种群密度(Population Density) 和 物种丰富度(Species Richness)。
- 前者关心的是“有多少只”(数量)。
- 后者关心的是“有多少种”(种类)。
当你走进一片热带雨林,你可能会看到 100 只蚂蚁,但这只代表 1 个物种;而如果你看到了 1 只猴子、1 只鹦鹉和 1 条蛇,虽然数量只有 3,但物种丰富度却是 3。
std::set(集合) 是 C++ STL 中最能体现“物种丰富度”特性的容器。它的核心特征是:自动去重(重复插入无效)和自动排序(内部通常是红黑树)。
为了考察 set 的插入(去重)、查找和统计大小,我为你构思了这道题目。
[OI 题库] 亚马逊雨林的物种普查 (Biodiversity Survey)
题目背景
“大自然厌恶重复,但它热爱多样性。”
你是一名生物学家,正在亚马逊雨林进行生物多样性调查。你的任务是记录你所见到的每一个生物。
由于雨林环境复杂,你可能会多次遇到同一种生物(例如,你今天早上看到了一只蓝摩尔法蝶,下午又看到了一只)。但在计算物种丰富度时,重复看到的生物只能算作一种。
你需要编写一个智能记录系统,帮助你过滤重复数据,并实时回答关于物种存在性的问题。
题目描述
系统需要处理 次操作,操作分为三种类型:
- 发现 (Observe):
1 name你在考察中发现了一个生物,其学名为name(字符串)。请将其加入数据库。- 注意:如果该物种已经在数据库中,系统会自动忽略,不会重复计数。
- 查证 (Check):
2 name你需要确认名为name的物种是否已经被记录过。- 如果已记录,输出
Yes;否则输出No。
- 如果已记录,输出
- 统计 (Report):
3输出当前的物种丰富度(即数据库中不同物种的总数量)。
输入格式
第一行一个整数 ,表示操作次数。 接下来 行,每行包含一个操作指令。
name是由英文字母组成的字符串(区分大小写)。
输出格式
- 对于操作
2,输出Yes或No。 - 对于操作
3,输出一个整数。 - 每个输出占一行。
样例数据
样例 1
输入 (Input)
8
1 Morpho
1 Jaguar
1 Morpho
3
2 Jaguar
2 Capybara
1 Capybara
3
输出 (Output)
2
Yes
No
3
样例解析 (Explanation)
1 Morpho:发现蓝闪蝶。集合变为{Morpho}。1 Jaguar:发现美洲豹。集合变为{Jaguar, Morpho}。1 Morpho:又发现蓝闪蝶。已存在,自动去重。集合仍为{Jaguar, Morpho}。3:统计丰富度。当前大小为 2。2 Jaguar:查证美洲豹。存在,输出 Yes。2 Capybara:查证水豚。不存在,输出 No。1 Capybara:发现水豚。集合变为{Capybara, Jaguar, Morpho}。3:统计丰富度。当前大小为 3。
数据范围
- 字符串长度 。
- 考察点:
set的自动去重特性和 的快速查找能力。
阿西莫夫的解题指南
这道题是 STL std::set 的教科书级应用。
- 去重:不需要像数组那样遍历查找“是否存在”,直接调用
st.insert(val)。如果元素已存在,set会什么都不做。 - 查找:使用
st.count(val)或者st.find(val)。count()返回 1 表示存在,0 表示不存在(因为 set 里没有重复元素)。- 这比在
vector中查找()要快得多()。
- 统计:
st.size()直接返回不同元素的个数。