只过了八个点
C++代码如下:
#include<bits/stdc++.h>
using namespace std;
int n,m,q; // 角色数量、角色关联个数、待检查的操作数
struct player{ // 角色结构体:资源请单
string name; // 角色id
vector<string> nv; // 操作
vector<string> no; // 种类
vector<string> nn; // 名称
};
vector<player> per(55);
unordered_map<string,int> mp_pid; // 角色id和其索引
unordered_map<string,vector<int>> ump; // 用户和角色id的关联
unordered_map<string,vector<int>> gmp; // 用户组和角色id的关联
int work(){
// 初始化读入
string user;
int ng;
cin >> user >> ng;
vector<string> groups; // 用户属于的组
for(int i = 0;i < ng;i++){
string s;
cin >> s;
groups.push_back(s);
}
string quire_v,quire_o,quire_n; // 查询的操作、种类、名称
cin >> quire_v >> quire_o >> quire_n;
// 所有角色
set<int> allp; // 存储该用户 及 用户组 对应的所有角色
// ump[user] : 用户对应的 所有 角色id vector
if (ump.find(user) == ump.end())
ump[user] = {};
for (auto it : ump[user])
allp.insert(it);
// gmp[g] : 用户组对应的 所有 角色id vector
for (auto g : groups){
if (gmp.find(g) == gmp.end()) {
gmp[g] = {}; // 显式初始化为空 vector
}
for (auto it : gmp[g])
allp.insert(it);
}
// 看是否存在角色能够进行对应操作 : quire_v,quire_o,quire_n
for(auto it : allp){ // 遍历角色: per[it] it 为对应 id
// 第一步: 检查操作:包含该操作 / "*"
int step1 = 0;
for(auto tv : per[it].nv){
if(tv == quire_v || tv == "*"){
step1 = 1;
break;
}
}
if(!step1) continue; // 不符合则换一个角色
// 第二步: 检查种类:包含种类 / "*"
int step2 = 0;
for(auto to : per[it].no){
if(to == quire_o || to == "*"){
step2 = 1;
break;
}
}
if(!step2) continue; // 不符合
// 第三步: 检查名称:包含名称 / 空数组
if(per[it].nn.size() == 0){ // 空数组
return 1;
}
for(auto tn : per[it].nn){ // 包含名称
if(tn == quire_n){
return 1;
}
}
}
return 0;
}
int main(){
// freopen("in.txt","r",stdin);
cin >> n >> m >> q;
// 角色
for(int i = 0;i < n;i++){
cin >> per[i].name;
mp_pid[per[i].name] = i;
int n_v,n_o,n_n;
cin >> n_v;
for(int j = 0;j < n_v;j++){
string t_v;
cin >> t_v;
per[i].nv.push_back(t_v);
}
cin >> n_o;
for(int j = 0;j < n_o;j++){
string t_o;
cin >> t_o;
per[i].no.push_back(t_o);
}
cin >> n_n;
for(int j = 0;j < n_n;j++){
string t_n;
cin >> t_n;
per[i].nn.push_back(t_n);
}
}
// 角色关联
for(int i = 0;i < m;i++){
string pname; // 角色名称
int ns; // 授权对象数量 、
cin >> pname >> ns;
int pid = mp_pid[pname];
for(int j = 1;j <= ns;j++){
char type; // 决定是 用户 / 用户组
cin >> type;
if(type == 'u'){
string s;
cin >> s;
ump[s].push_back(pid);
}else{ // 用户
string s;
cin >> s;
gmp[s].push_back(pid);
}
}
}
while(q--) cout << work() << "\n";
return 0;
}
/*====================================
基于角色的 授权 模型:
1. 角色(string) -> 资源清单 {操作(vector)、种类(vector)、名称(vector)}
2. 用户:名称(string) + 用户组(vector) -> U{角色} 并集
3.待授权的行为: 主体(用户、用户组)+ 操作 + 资源 (种类 / 名称)
**按照每次待授权的行为中给出的信息独立判断 == 用户及其用户组
4. 角色关联: 用户和角色的关系
角色(string) -> 授权对象清单 (单用户名/多用户名/用户组)
=====================================
判断角色能够进行操作:
1.检查操作:包含该操作 / "*"
2.检查种类:包含种类 / "*"
3.检查名称:包含名称 / 空数组
=====================================
判断用户执行操作:
1.检查角色授权清单
2.检查该角色能否进行操作
=====================================*/
`