CSP 2021-6 第三题 角色授权
题目链接
代码只有20分,懂得人帮忙看看(注释都挺全的)
样例:
1 2 3
op 1 open 1 door 0
op 1 g sre
op 1 u xiaop
xiaoc 2 sre ops open door room302
xiaop 1 ops open door room501
xiaoc 2 sre ops remove door room302
样例输出:
1
1
0
代码:
#include <bits/stdc++.h>
using namespace std;
const int N = 505;
//角色数量、角色关联数量和待检查的操作数量。
int n,m,q;
map<string,int> id; // 记录角色与id的映射关系
// 角色类
struct JueSe{
// .empty()判断是否为空
string name;
map<string,bool> nv; // 操作
map<string,bool> no; // 资源种类
map<string,bool> nn; // 资源名称
}juese[N];
// 角色与用户或者用户组关联
struct Relation{
string j_name; // 角色名称
// int ns; // 授权对象数量 对用户或者用户组
map<string,bool> mp1,mp2;
}rel[N];
int main()
{
cin >> n >> m >> q;
// 输入角色
for(int i=1;i<=n;i++){
string s;
cin >> s;
juese[i].name = s;
id[s] = i;
int nvv,noo,nnn;
cin >> nvv;
for(int j=0;j<nvv;j++){
cin >> s;
juese[i].nv[s] = 1;
}
cin >> noo;
for(int j=0;j<noo;j++){
cin >> s;
juese[i].no[s] = 1;
}
cin >> nnn;
for(int j=0;j<nnn;j++){
cin >> s;
juese[i].nn[s] = 1;
}
}
// 输入角色关联
for(int i=1;i<=m;i++){
string s,s1;
cin >> s;
rel[i].j_name = s;
int nss;
cin >> nss;
for(int j=1;j<=nss;j++){
cin >> s >> s1;
if(s=="u") rel[i].mp1[s1] = 1; //用户
else rel[i].mp2[s1] = 1;
}
}
vector<string> v;
while(q--){
string user; //用户名称
int ng; //用户所属用户组数量
cin >> user;
cin >> ng;
v.clear();
for(int i=1;i<=m;i++){
if(rel[i].mp1.count(user)) v.push_back(rel[i].j_name);
}
for(int i=1;i<=ng;i++){
string s;
cin >> s;
if(rel[i].mp2.count(s)){
v.push_back(rel[i].j_name);
}
}
string a,b,c;
cin >> a >> b >> c;
//判断一个角色能否对某个资源执行某个操作的过程
bool ff = false;
for(int i=0;i<(int)v.size();i++){
bool flag = true;
int p = id[v[i]];
// chk1:检查操作清单
if(!juese[p].nv.count(a) && !juese[p].nv.count("*")) flag = false;
// chk2:检查资源种类清单
if(!juese[p].no.count(b) && !juese[p].no.count("*")) flag = false;
// chk3:检查资源名称清单
if(!juese[p].nn.count(c) && (!juese[p].nn.empty())) flag = false;
if(flag){
ff = true;
break;
}
}
if(ff){
puts("1");
}else{
puts("0");
}
}
return 0;
}
10.1更新:
第81行少了遍历m次关系,如下:
for(int i=1;i<=ng;i++){
string s;
cin >> s;
for(int j=1;j<=m;j++)
if(rel[j].mp2.count(s)){
v.push_back(rel[j].j_name);
}
}