#include <iostream>
#include <bits/stdc++.h>
using namespace std;
int n,m,q;
struct Role//角色
{
string name;
set<string> oper;//角色可以进行的操作
set<string> zy,zyname;//资源和资源名
};
//unoder_map比map快了0.8秒左右
unordered_map<string,Role> Map;
unordered_map<string,vector<string>> connect;
inline bool panduan(string name,string s1,string s2,string s3)
{
Role &temp=Map[name];//关键步骤
//判断三个条件
//利用count函数可以快速判断出容器中是否含有某个元素从而快速判断,不用从头到尾把容器遍历一遍
if(temp.oper.count("*")||temp.oper.count(s1))
{
if(temp.zy.count("*")||temp.zy.count(s2))
{
if(temp.zyname.count("*")||temp.zyname.count(s3)||temp.zyname.empty())
{
return true;
}
}
}
return false;
}
inline bool judge(const vector<string>& names)
{
string name, oper, kind, sname;
cin >> oper >> kind >> sname;
for (int i=0;i<names.size();i++)
{
name=names[i];
if (!connect.count(name)) continue;
vector<string> vec = connect[name];
for (int j=0;j<vec.size();j++)
{
string roleName=vec[j];
Role &r = Map[roleName];//这一步加上用引用可以节省很多时间,节约时间空间,减少赋值操作
if (r.oper.count("*") || r.oper.count(oper))
{
if (r.zy.count("*") || r.zy.count(kind))
{
if (r.zyname.empty() || r.zyname.count(sname)) return true;
}
}
}
}
return false;
}
int main()
{
//提高cin,cout的速度
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
cin>>n>>m>>q;
//输入角色 v1
for(int i=1;i<=n;i++)
{
Role temp;
int nv,no,nn;
string name,s;
cin>>name;
temp.name=name;
cin>>nv;
while(nv--)
{
cin>>s;
temp.oper.insert(s);
}
cin>>no;
while(no--)
{
cin>>s;
temp.zy.insert(s);
}
cin>>nn;
while(nn--)
{
cin>>s;
temp.zyname.insert(s);
}
Map[name]=temp;
}
//输入关联 v2
for(int i=1;i<=m;i++)
{
string name,s1,s2;
cin>>name;
int ns;
cin>>ns;
while(ns--)
{
cin>>s1>>s2;
connect[s2].push_back(name);
}
}
//输入用户
while(q--)
{
string name,g,s,s1,s2,s3;
int ng;
cin>>name>>ng;
vector<string> gg;
gg.push_back(name);
while(ng--)
{
cin>>s;
gg.push_back(s);
}
//用judge函数的方法:(这里用judge函数)
if(judge(gg)) cout <<"1\n";
else cout << "0\n";
//用panduan函数的方法:(已经注释)
//遍历角色关联数组,匹配这个人可以执行哪一个角色的操作
// bool pp=0;//判断是否可执行操作
// cin>>s1>>s2>>s3;
// for(int i=0;i<gg.size();i++)
// {
// string name=gg[i];
// if(!connect.count(name)) continue;//先判断在关联数组中是否有这个人的名字或者这个人所属的群组名
// vector<string> temp=connect[name];
// for(int j=0;j<temp.size();j++)//如果存在直接访问其所包含的角色
// {
// if(panduan(temp[j],s1,s2,s3))
// {
// pp=1;
// break;
// }
// }
// if(pp) break;
// }
//
//
// if(pp) printf("1\n");
// else printf("0\n");
}
return 0;
}
202206-3 角色授权 100分(含注释)(两种判断方法)
于 2022-08-31 15:05:01 首次发布