被卡时间卡了很久,最后还是过了。总结下来大概就是以下几点经验。
1.容器的选用方面,用set换vector,用unordered_map换map提高效率。
2.用map<string,role>存储角色信息相比直接开roles数组要高明,前者可以很快速地通过角色名找信息而不必逐个遍历。
3.仅针对这题来说,用户名和用户组名其实也没必要区分。
总的来说,找好合适的存储方式,这道题还是不难的。也正是因为似乎简单的遍历就能解决问题,在选择容器时才要仔细考虑,避免被卡时间。
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
struct role {
set<string>oprate;
set<string>resourcekind;
set<string>resource;
};
unordered_map<string, role>roles;
//前一项表示角色名,后一项表示该角色对应的操作,资源等
unordered_map<string, set<string>>assouserorgroup;
//前一项表示用户或用户组名称,后一项表示角色名称
int main() {
ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);//加快输入输出
int n, m, q;
cin >> n >> m >> q;
while (n--) {
string name;
int nv;
cin >> name >> nv;
while (nv--) {
string op;cin >> op;
roles[name].oprate.insert(op);
}
int no;cin >> no;
while (no--) {
string rk;cin >> rk;
roles[name].resourcekind.insert(rk);
}
int nn;cin >> nn;
while (nn--) {
string res;cin >> res;
roles[name].resource.insert(res);
}
}
while (m--) {
string rolename;cin >> rolename;
int ns;cin >> ns;
while (ns--) {
string kind;
string name;
cin >> kind >> name; //后一项是用户组或用户名称
assouserorgroup[name].insert(rolename);
}
}
while (q--) {
string username;
set<string> userorgroupname;
int ng;
cin >> username >> ng;
userorgroupname.insert(username);
while (ng--) {
string gname;
cin >> gname, userorgroupname.insert(gname);
//用户组名和用户名可以不做区分,似乎二者也不会重名
}
string opratename;cin >> opratename;
string resourcekind;cin >> resourcekind;
string resourcename;cin >> resourcename;
set<string>ansrolename;
int flag = 0;
for (auto i : userorgroupname) {//对于每一个要查的用户名或用户组名
if (assouserorgroup.count(i)) {//如果关联里有关联到这个用户名或用户组名,取出对应的角色名集合 assouserorgroup[i]
for (auto j :assouserorgroup[i]) {//对于集合中每一个角色名,筛查对应的操作,资源种类和资源。一旦有一个符合要求就停止循环
if ((roles[j].oprate.count(opratename)
|| (roles[j].oprate.count("*")) )
&& (roles[j].resourcekind.count(resourcekind)
|| (roles[j].resourcekind.count("*")) )
&& (roles[j].resource.count(resourcename) || roles[j].resource.size() == 0)) {
flag = 1;
break;
}
}
if (flag == 1)
break;
}
}
cout << flag << "\n";
}
return 0;
}