题意
给n个需要忽视的目录,m个需要保护的目录,求gitignore的最小行数
Solution
用保护去检索ignore。
#include <bits/stdc++.h>
using namespace std;
int t, n, m;
vector<string> v1, v2;
set<string> prt, vis;
int main() {
ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
cin >> t;
while (t--) {
cin >> n >> m;
string s;
v1.clear(), v2.clear(), vis.clear(), prt.clear();
for (int i = 0; i < n; i++) cin >> s, v1.push_back(s);
for (int i = 0; i < m; i++) cin >> s, v2.push_back(s);
for (int i = 0; i < m; i++) {
string s = "";
for (char &c : v2[i]) { //建立保护清单
if (c == '/') prt.insert(s); //所有的父级目录都被保护
s += c;
}
}
int ans = n; //假设全都单独写入gitignore
for (int i = 0; i < n; i++) {
string s = "";
for (char &c : v1[i]) {
if (c == '/') {
if (!prt.count(s)) { //没有被保护
if (vis.count(s)) --ans; //存在同级目录
else vis.insert(s);
break; //子目录不再检索
} //此处是一个贪心的最优:子目录可以,且父目录未被保护,肯定是父目录最优
}
s += c;
}
}
cout << ans << endl;
}
return 0;
} map写法亦可
#include <bits/stdc++.h>
using namespace std;
int t, n, m;
vector<string> v1, v2;
map<string, bool> prt, vis;
int main() {
ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
cin >> t;
while (t--) {
cin >> n >> m;
string s;
v1.clear(), v2.clear(), vis.clear(), prt.clear();
for (int i = 0; i < n; i++) cin >> s, v1.push_back(s);
for (int i = 0; i < m; i++) cin >> s, v2.push_back(s);
for (int i = 0; i < m; i++) {
string s = "";
for (char &c : v2[i]) {
if (c == '/') prt[s] = 1;
s += c;
}
}
int ans = n;
for (int i = 0; i < n; i++) {
string s = "";
for (char &c : v1[i]) {
if (c == '/') {
if (!prt[s]) {
if (vis[s]) --ans;
else vis[s] = 1;
break;
}
}
s += c;
}
}
cout << ans << endl;
}
return 0;
} 
京公网安备 11010502036488号