華為0821筆試第三題筆記-回溯+剪枝

axuu發表於2024-09-02

知識點:

解題方法:回溯+剪枝

新接觸的資料型別:

#include <unordered_map>
#include <unordered_set>

1.#include <unordered_map>

#include <unordered_set>

#include <climits>分別是什麼?

#include <unordered_map>#include <unordered_set> 是 C++ 標準庫中的標頭檔案,它們提供了無序對映(雜湊表)和無序集合的資料結構。

  1. #include <unordered_map>:

    • 這是一個無序對映容器,使用雜湊表實現。它提供了鍵值對(key-value pair)儲存的功能,能夠根據鍵快速查詢對應的值。
    • std::map 不同,unordered_map 不保持元素的順序,因此在進行查詢、插入和刪除操作時平均時間複雜度為 O(1)。
    • 適用於需要快速查詢和不關心元素順序的場景。
  2. #include <unordered_set>:

    • 這是一個無序集合容器,同樣使用雜湊表實現。它僅儲存鍵(key),不儲存值。
    • 無序集合不允許重複的元素,且元素的順序是不確定的。
    • 插入、刪除和查詢操作的平均時間複雜度為 O(1),適用於需要快速判斷元素是否存在的場景。
  3. #include <climits>:

    • 這是一個包含整數型別的各種特性的標頭檔案,定義了各種整型資料型別的限制(如 INT_MAXINT_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):

    • 預設情況下,cincout 是“繫結”(tied)在一起的,這意味著在使用 cin 之前,cout 會自動重新整理其緩衝區。這是為了確保所有輸出都在輸入之前完成,從而避免輸出混亂。
    • 換句話說,如果 cincout 是繫結的,那麼每次你使用 cin 時,cout 都會呼叫 flush,將所有未輸出的內容立即寫入到輸出流。
  • cin.tie(0) 的作用:

    • cin.tie(0); 解除 cincout 之間的繫結(tie)。0 表示不繫結任何流。
    • 解除繫結後,cin 的操作將不再自動重新整理 cout,這樣可以減少不必要的重新整理操作,提高程式的執行效率。

使用場景

  • 當你需要大量輸入輸出操作時,解除繫結可以顯著提高效能,因為它減少了緩衝區重新整理帶來的效能開銷。
  • 在競賽程式設計和需要高效能的場景下,解除繫結 cincout 是一個常見的最佳化手段。

這種最佳化方式適用於不依賴於輸入輸出順序的程式。例如,如果你需要先讀取所有輸入,然後進行計算和輸出,這種設定會很有用。

注意事項

  • 雖然 cin.tie(0); 可以提高效能,但在某些場景下(尤其是輸入輸出順序非常重要的場合),不正確地使用可能會導致未預期的輸出行為。因此,只有在明確知道輸入輸出順序不會受到影響時才使用這種最佳化。

6.times.resize(jobNum); 是 C++ 中 std::vector 容器的一個函式呼叫,用來調整 vector 的大小。

7.usd.size()unordered_set(或者其他標準庫容器,如 vectorset 等)的成員函式,它返回當前集合中元素的數量。

  • 返回型別是 std::size_t,這是一個無符號整數型別,通常用於表示容器中元素的數量或陣列大小。
  • std::size_t 的型別定義通常是 unsigned intunsigned long,這取決於編譯器和作業系統。它的設計目的是為了確保足夠大的範圍來表示任何可能的容器大小。

(int)usd.size() 是對 usd.size() 的強制型別轉換,將其轉換為 int 型別。

為什麼要進行型別轉換?

在某些情況下,可能需要將 size_t 型別轉換為 int,例如:

  • 比較操作:有些情況下,你可能想要將 size_tint 進行比較。如果你直接比較一個無符號型別(如 size_t)和一個有符號型別(如 int),可能會導致編譯器警告或者錯誤,甚至導致錯誤的邏輯,因為無符號和有符號數的比較有時候會產生不可預期的結果。(本題就是這樣的情況)

    例如,if (usd.size() >= 0) 對於 size_t 型別的 usd.size() 總是 true,因為 size_t 是無符號型別,不可能小於 0。強制轉換為 int 可以避免這種錯誤。

  • 函式引數:一些函式引數需要 int 型別的值。如果直接傳遞 size_t 可能導致編譯錯誤或警告,因此使用 (int) 進行型別轉換。

相關文章