PAT A1149 Dangerous Goods Packaging
- 思路 1:hash表
- 遍历时,将该所有与该元素相冲的标记出来
- 之后如果遍历到那个元素,输出No,如果遍历完一组数据,输出Yes
- code 1:
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
const int maxn = 110000;
bool has[maxn];
vector<int> v[maxn];
int main(){
int n, m, k, t1, t2, tmp;
scanf("%d %d", &n, &m);
for(int i = 0; i < n; ++i){
scanf("%d %d", &t1, &t2);
v[t1].push_back(t2);
v[t2].push_back(t1);
}
for(int i = 0; i < m; ++i){
scanf("%d", &k);
bool flag = false;
fill(has, has+maxn, false);
for(int j = 0; j < k; ++j){
scanf("%d", &tmp);
for(int k = 0; k < v[tmp].size(); k++){
has[v[tmp][k]] = true;
}
if(has[tmp]){
flag = true;
// break; //!!!:Wrong 1:不能提前break;后面还有数据要输入
}
}
if(flag) printf("No\n");
else printf("Yes\n");
}
return 0;
}
- 思路 2:map<int, vector > mp
- 用map记录所有组相冲物品,用一个vector记录一组数据,同时把所有元素用hash表标记
- 遍历这个vector,对每个元素,通过map,查看和他相冲的元素是否也在组里(hash表被标记)
- code 2:
#include <iostream>
#include <map>
#include <vector>
using namespace std;
const int maxn = 100010;
map<int, vector<int> > mp;
bool has[maxn];
int main(){
int n, m, k, t1, t2, tmp;
scanf("%d %d", &n, &m);
for(int i = 0; i < n; ++i){
scanf("%d %d", &t1, &t2);
mp[t1].push_back(t2);
mp[t2].push_back(t1);
}
for(int i = 0; i < m; ++i){
scanf("%d", &k);
vector<int> tmp(k);
bool flag = false;
fill(has, has+maxn, false);
for(int j = 0; j < k; ++j){
scanf("%d", &tmp[j]);
has[tmp[j]] = true;
}
for(int j = 0; j < k; ++j){
for(int l = 0; l < mp[tmp[j]].size(); ++l){
if(has[mp[tmp[j]][l]]){
flag = true;
break;
}
}
}
printf("%s\n", flag ? "No" : "Yes");
}
return 0;
}
-
思路 2:
对象表由一对一变成多对多:改用二维vector<int> v[maxn];
数组或用map<int, vector> mp;
-
code:二维vector
#include <bits/stdc++.h>
using namespace std;
const int maxn = 100100;
vector<int> v[maxn];
//map<int, vector<int> > mp;
bool has[maxn];
int main(){
int n, m;
scanf("%d %d", &n, &m);
for(int i = 0; i < n; ++i){
int tmp1, tmp2;
scanf("%d %d", &tmp1, &tmp2);
v[tmp1].push_back(tmp2);
v[tmp2].push_back(tmp1);
//mp[tmp1].push_back(tmp2);
//mp[tmp2].push_back(tmp1);
}
for(int i = 0; i < m; ++i){
int k;
bool flag = true;
scanf("%d", &k);
memset(has, 0, sizeof(has));
for(int j = 0; j < k; ++j){
int tmp;
scanf("%d", &tmp);
if(flag && has[tmp] == false){
for(int l = 0; l < v[tmp].size(); ++l)
has[v[tmp][l]] = true;
}else{
flag = false;
}
}
if(flag) printf("Yes\n");
else printf("No\n");
}
return 0;
}
-
思路 3:使用Multimap
-
T2 code:
#include <bits/stdc++.h>
using namespace std;
multimap<int, int> mp;
int main(){
int n, m;
scanf("%d %d", &n, &m);
for(int i = 0; i < n; ++i){
int g1, g2;
scanf("%d %d", &g1, &g2);
mp.insert(make_pair(g1, g2));
mp.insert(make_pair(g2, g1));
}
for(int i = 0; i < m; ++i){
scanf("%d", &n);
bool flg = true;
unordered_map<int, bool> mark;
for(int j = 0; j < n; ++j){
int tmp;
scanf("%d", &tmp);
if(mark[tmp] == false){
auto it = mp.lower_bound(tmp), end = mp.upper_bound(tmp);
// auto it = mp.equal_range(tmp).first, mp.equal_range(tmp).second;
while(it != end){
mark[it->second] = true;
++it;
}
}else if(flg){
printf("No\n");
flg = false;
}
}
if(flg) printf("Yes\n");
}
return 0;
}