洛谷:P3405:Cities and States S


洛谷:P3405:Cities and States S

Table of Contents

题目

P3405:Cities and States S

分析

这是一道提升STL、特别是STL中的map很好的题目。我们这里用到了unordered_map,因为它就是用了本章学习要点“哈希”来实现的。

unordered_map 是C++11引入的哈希表容器,它:

  • 通过哈希函数实现快速查找,平均时间复杂度为O(1)
  • 不像普通的map,元素不会自动排序
  • 适用于需要频繁查找、插入的场景
  • 使用前需要包含<unordered_map>头文件

基本用法示例:

unordered_map<string, int> hash_map;
hash_map["key"] = 100;  // 插入或修改
int value = hash_map["key"];  // 查找

map可以非常直观地用现实中的“字典”来类比。它们都是用一个关键字(key)来找到其值(value)。最重要的一点,是在map的所有项中,key必须是唯一的,而其value可以是一个“复合”类型(比如本题解法中用到的一个结构的列表)。

struct City {
    string name; //城市名
    string state; //所属的州
};

unordered_map<string, vector<City>> cityMap;

那么,这个mapkey用什么比较好?用城市名的前两个字母?还是州名的前两个字母?注意到我们map的声明:它的值其实是一个vector,也就是说,可以是多个的。

同时,这个vector又是City类型的,包含了namestate。比如说,假定这个keyFL,我们既可以认为City的缩写是FL又可以认为州的缩写是FL。本题的解法是将城市的缩写作为key,于是在首次遍历找到某个城市的缩写时,再次遍历该城市所包含的City,找到相关的city.state即可。

这里最烦的,是有两个遍历,有两个iterator,需要注意如何访问每个iterator的成员,每个成员各自的成员。

graph TD A[遍历cityMap中的每个entry] -->|city1=entry.second| B[遍历entry对应的城市列表city1] B -->|"city1={name, state}"| C{在cityMap中查找
以city1.state为key的城市} C -->|找到| D[遍历匹配到的城市列表city2] D --> E{检查条件:
1. city2.state == entry.first
2. city1.state != city2.state} E -->|满足条件| F[count++]

这里出现了内层使用结构成员访问(city1.statecity2.state),外层使用mapfirst/secondentry.first)访问的“混乱”局面。但只要记住题目要求,想清楚每个迭代子代表哪个数据类型,还是可以驾驭的。

答案

Solution

思考

能否用州名缩写作为key?应该也是可以的。有兴趣的同学可以自行完成。

最后输出的值需要除以2,因为这样的配对关系一定是成对出现的。

上一篇 下一篇