知識點:
解題方法:回溯+剪枝
新接觸的資料型別:
#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)
進行型別轉換。