【PAT甲级题解记录】1149 Dangerous Goods Packaging (25 分)
前言
Problem:1149 Dangerous Goods Packaging (25 分)
Tags:map的运用 模拟
Difficulty:
剧情模式想流点汗想流点血死而无憾
问题描述
有一批化学货品,会发生反应的货品不能放在一个集装箱,现在两两给定会互相发生反应的化学货品,再给出每一个集装箱的货品清单,分别求这些集装箱是否可安全装箱。
解题思路
首先明确一点,若AB会反应,BC会反应,那不代表AC会反应,所以这不是一个并查集的问题,而是一个映射的问题,用map可轻松解决。
有俩个思路:
- 使用
map<int,map<int,int> >
保存输入,输入时使两个会反应的货品之间置1,但在检查集装箱时,需要暴力检查每两个货品之间的反应关系是否为1,很可能超时。 - 使用
map<int,vector<int> >
保存输入, 输入时保存与当前货品会发生反应的货品列表,这样在检查集装箱时,只需先初始化一个映射数组存储哪些货品出现了,然后遍历map中各个货物的反应列表,看是否有反应物出现在这个集装箱中。 - 或者同样使用
map<int,vector<int> >
保存输入,设置一个反应货物集合,遍历集装箱货物时需检查此货物是否出现在集合中,若出现说明该货物不可放入,若没有出现则将会于该货物反应的货物入集合。
参考代码
- 思路2
/*
* @Author: Retr0.Wu
* @Date: 2022-02-22 01:06:24
* @Last Modified by: Retr0.Wu
* @Last Modified time: 2022-02-22 15:02:51
*/
#include <bits/stdc++.h>
#include <unordered_map>
using namespace std;
unordered_map<int, vector<int> > mp; // 可用无序map提速,直接map也没问题
int main()
{
int N, M;
cin >> N >> M;
for (int i = 1; i <= N; i++)
{
int s1, s2;
cin >> s1 >> s2;
mp[s1].push_back(s2);
mp[s2].push_back(s1);
}
while (M--)
{
int K;
cin >> K;
int flag = 1;
vector<int> s(K);
vector<int> exist(100000,0);
for (int i = 0; i < K; i++)
{
cin >> s[i];
exist[s[i]] = 1;
}
for(int i=0;i<K&&flag;i++){
for(int j = 0 ; j< mp[s[i]].size();j++){
if(exist[mp[s[i]][j]]){ // 在这组货物中有与第i个货物反应的货物
flag = 0;
break;
}
}
}
if(flag){
cout<<"Yes"<<endl;
}
else{
cout<<"No"<<endl;
}
}
return 0;
}
- 思路3
#include<iostream>
#include<vector>
#include<set>
#include<map>
using namespace std;
int N; // the number of pairs of incompatible goods (1e4)
int M; // the number of lists of goods to be shipped (1e2)
map<string,vector<string>> incompatible;
void init() {
cin >> N >> M;
for (int i = 0; i < N; ++i) {
string a, b;
cin >> a >> b;
incompatible[a].push_back(b);
incompatible[b].push_back(a);
}
}
void solution_1149() {
init();
for (int i = 0; i < M; ++i) {
set<string> in_pack; // 将不可兼容货物组成一个集合
bool flag = true;
int K;
cin >> K;
for (int j = 0; j < K; ++j) {
string s;
cin>>s;
if(in_pack.count(s)){
flag = false;
}
for(int j=0;j<int(incompatible[s].size());++j){
in_pack.insert(incompatible[s][j]);
};
}
if(flag){
cout<<"Yes"<<endl;
}
else{
cout<<"No"<<endl;
}
}
}
int main() {
solution_1149();
return 0;
}
总结
注意方法的选择,类似的方法在实际效率上可能截然不同,想清楚再开题防止误入歧途。