PAT甲級1149Dangerous Goods Packaging
阿新 • • 發佈:2020-09-02
題目連結
https://pintia.cn/problem-sets/994805342720868352/problems/1038429908921778176
題目要求
當用容器運輸貨物時,一些貨物是不能裝在一起的。現在告訴你哪些貨物能裝在一起,給你一些貨物,請判斷這些貨物是否可以被裝在一起
-
輸入
-
N:不能裝在一起的貨物對的數量,不超過10000
-
M:要運輸的貨物的組數,不超過100
-
N組不能裝在一起的貨物:每組包括兩個貨物索引
-
M組貨物
第一個數字K(不超過1000)是貨物的數量,然後剩下的是貨物索引(5位數字)
-
-
輸出
對於M組貨物中的每組,如果其中沒有不可以裝在一起的貨物則輸出Yes,否則輸出No
題解一
思路
這個思路會超時
- 通過map和hash記錄兩個貨物是否可以被裝在一起,相當於一個鄰接矩陣
- 為什麼不定義矩陣?如果要用矩陣,在這裡就需要定義一個100000×100000的bool矩陣,大概會佔用10GB,而記憶體限制是64MB。
- 對於每組貨物,兩兩判斷是否不相容,是一個兩層迴圈,時間複雜度是\(K^2\),再算上M組查詢,時間複雜度就是\(MK^2\),最大值為100×1000×1000=1e8,大概會耗時1秒,肯定會超過400ms的時間限制。
程式碼
// Problem: PAT Advanced 1149 // URL: https://pintia.cn/problem-sets/994805342720868352/problems/1038429908921778176 // Tags: Graph Map Hash #include <iostream> #include <unordered_map> #include <vector> using namespace std; int main() { int n, m, k; scanf("%d %d", &n, &m); int good1, good2; unordered_map<int, bool> incompatible; // 通過map和hash記錄兩個貨物是否可以被裝在一起 while (n--){ // 通過map和hash記錄兩個貨物是否可以被裝在一起 scanf("%d %d", &good1, &good2); incompatible[good1 * 100000 + good2] = true; incompatible[good2 * 100000 + good1] = true; } while (m--){ //判斷m組貨物 scanf("%d", &k); vector<int> goods(k); for (int i = 0; i < k; i++) // 記錄k個貨物 scanf("%d", &goods[i]); bool isYes = true; for(int i = 0; i < k - 1; i++){ //判斷k個貨物是否可以放在一起 good1 = goods[i]; for (int j = i + 1; j < k; j++){ good2 = goods[j]; if (incompatible[good1 * 100000 + good2] || incompatible[good2 * 100000 + good1]){ isYes = false; break; } } } // 輸出結果 if (isYes) printf("Yes\n"); else printf("No\n"); } return 0; }
題解二
思路
-
使用鄰接表儲存每個貨物的不能裝在一起的貨物
-
對於每組貨物,使用一維陣列儲存每個貨物是否在這組貨物中
-
查詢鄰接表,並通過一維陣列判斷每個貨物的不相容貨物是否出現在這組貨物中
這裡也是用了兩層迴圈,但這兩層迴圈的時間複雜度是\(N\),再算上M組查詢,時間複雜度就是\(MN\),最大值為100×10000=1e6。
程式碼
// Problem: PAT Advanced 1149 // URL: https://pintia.cn/problem-sets/994805342720868352/problems/1038429908921778176 // Tags: Graph Map Hash #include <iostream> #include <vector> using namespace std; vector<int> incompatible[100000]; // 鄰接表,貨物與哪些貨物不能裝在一起 int main() { int n, m, k, good1, good2; scanf("%d %d", &n, &m); while (n--){ // 建立鄰接表 scanf("%d %d", &good1, &good2); incompatible[good1].push_back(good2); incompatible[good2].push_back(good1); } while (m--){ // m組貨物 scanf("%d", &k); vector<int> goods(k); // 該組貨物 bool contained[100000]={false}; // 該組貨物中有哪些貨物 for (int i = 0; i < k; i++){ // 記錄該組貨物 scanf("%d", &goods[i]); contained[goods[i]] = true; } bool isYes = true; for (int i = 0; i < k; i++){ // 查詢鄰接表,並通過一維陣列判斷每個貨物的不相容貨物是否出現在這組貨物中 for (int j = 0; j < incompatible[goods[i]].size(); j++){ if (contained[incompatible[goods[i]][j]]){ isYes = false; break; } } } // 輸出結果 if (isYes) printf("Yes\n"); else printf("No\n"); } return 0; }
參考連結
https://blog.csdn.net/liuchuo/article/details/82560836
作者:@臭鹹魚
轉載請註明出處:https://www.cnblogs.com/chouxianyu/
歡迎討論和交流!