华为0821笔试第三题笔记-回溯+剪枝
知识点:
解题方法:回溯+剪枝
新接触的数据类型:
#include <unordered_map>
#include <unordered_set>
1.#include <unordered_map>
#include <unordered_set>
#include <climits>分别是什么?
#include <unordered_map>
和 #include <unordered_set>
是 C++ 标准库中的头文件,它们提供了无序映射(哈希表)和无序集合的数据结构。
-
#include <unordered_map>
:- 这是一个无序映射容器,使用哈希表实现。它提供了键值对(key-value pair)存储的功能,能够根据键快速查找对应的值。
- 与
std::map
不同,unordered_map
不保持元素的顺序,因此在进行查找、插入和删除操作时平均时间复杂度为 O(1)。 - 适用于需要快速查找和不关心元素顺序的场景。
-
#include <unordered_set>
:- 这是一个无序集合容器,同样使用哈希表实现。它仅存储键(key),不存储值。
- 无序集合不允许重复的元素,且元素的顺序是不确定的。
- 插入、删除和查找操作的平均时间复杂度为 O(1),适用于需要快速判断元素是否存在的场景。
-
#include <climits>
:- 这是一个包含整数类型的各种特性的头文件,定义了各种整型数据类型的限制(如
INT_MAX
,INT_MIN
等)。 - 常用来获取整数类型的最大值和最小值,确保程序的健壮性,防止溢出或其他数据范围相关的问题。
- 这是一个包含整数类型的各种特性的头文件,定义了各种整型数据类型的限制(如
2.为什么做代码题目一般会把#include <algorithm>带上?
#include <algorithm>
是 C++ 标准库中的一个头文件,它包含了大量常用的算法函数。这些函数可以用于对容器(如数组、向量、列表等)进行操作,例如排序、查找、修改、排列等。<algorithm>
提供的函数大部分是模板函数,可以与各种数据类型和容器类型一起使用。
3.unordered_map<int, unordered_set<int>> mutex;
是 C++ 中一种复合数据结构的声明
4.mutex[u].count(i)
中的 count
函数用于检查特定元素是否存在于一个 unordered_set
中
unordered_map<int, unordered_set<int>> mutex; bool check(int i, const unordered_set<int>& usd){ for(int u : usd){ if(mutex[u].count(i) || mutex[i].count(u)) return false; } return true; }
count
函数的具体作用
mutex[u].count(i)
返回一个整数:- 如果
i
存在于mutex[u]
对应的unordered_set
中,count(i)
返回1
。 - 如果
i
不存在,count(i)
返回0
。
- 如果
因此,mutex[u].count(i)
用于检查元素 i
是否存在于键 u
对应的集合中。
5.cin.tie(0);
是 C++ 中用来优化输入输出性能的一个技巧。
-
流的绑定(Tie):
- 默认情况下,
cin
和cout
是“绑定”(tied)在一起的,这意味着在使用cin
之前,cout
会自动刷新其缓冲区。这是为了确保所有输出都在输入之前完成,从而避免输出混乱。 - 换句话说,如果
cin
和cout
是绑定的,那么每次你使用cin
时,cout
都会调用flush
,将所有未输出的内容立即写入到输出流。
- 默认情况下,
-
cin.tie(0)
的作用:cin.tie(0);
解除cin
与cout
之间的绑定(tie)。0
表示不绑定任何流。- 解除绑定后,
cin
的操作将不再自动刷新cout
,这样可以减少不必要的刷新操作,提高程序的执行效率。
使用场景
- 当你需要大量输入输出操作时,解除绑定可以显著提高性能,因为它减少了缓冲区刷新带来的性能开销。
- 在竞赛编程和需要高性能的场景下,解除绑定
cin
和cout
是一个常见的优化手段。
这种优化方式适用于不依赖于输入输出顺序的程序。例如,如果你需要先读取所有输入,然后进行计算和输出,这种设置会很有用。
注意事项
- 虽然
cin.tie(0);
可以提高性能,但在某些场景下(尤其是输入输出顺序非常重要的场合),不正确地使用可能会导致未预期的输出行为。因此,只有在明确知道输入输出顺序不会受到影响时才使用这种优化。
6.times.resize(jobNum);
是 C++ 中 std::vector
容器的一个函数调用,用来调整 vector
的大小。
7.usd.size()
是 unordered_set
(或者其他标准库容器,如 vector
、set
等)的成员函数,它返回当前集合中元素的数量。
- 返回类型是
std::size_t
,这是一个无符号整数类型,通常用于表示容器中元素的数量或数组大小。 std::size_t
的类型定义通常是unsigned int
或unsigned long
,这取决于编译器和操作系统。它的设计目的是为了确保足够大的范围来表示任何可能的容器大小。
(int)usd.size()
是对 usd.size()
的强制类型转换,将其转换为 int
类型。
为什么要进行类型转换?
在某些情况下,可能需要将 size_t
类型转换为 int
,例如:
-
比较操作:有些情况下,你可能想要将
size_t
和int
进行比较。如果你直接比较一个无符号类型(如size_t
)和一个有符号类型(如int
),可能会导致编译器警告或者错误,甚至导致错误的逻辑,因为无符号和有符号数的比较有时候会产生不可预期的结果。(本题就是这样的情况)例如,
if (usd.size() >= 0)
对于size_t
类型的usd.size()
总是true
,因为size_t
是无符号类型,不可能小于 0。强制转换为int
可以避免这种错误。 -
函数参数:一些函数参数需要
int
类型的值。如果直接传递size_t
可能导致编译错误或警告,因此使用(int)
进行类型转换。