题目
思路
无脑建立映射关系即可
题解
#include<bits/stdc++.h>
using namespace std;
typedef unordered_map<string,bool> zz;
int n,m,q;
// 角色性质结构体
struct node1
{
zz m1,m2,m3;
// m1 表示 操作清单中的操作是否存在的映射
// m2 表示 资源种类清单中的资源是否存在的映射
// m3 表示 资源名称清单中的资源名称是否存在的映射
};
// 定义角色名称与角色性质结构体的映射关系
unordered_map<string,node1>m0;
// 定义角色关联与角色之间的映射关系
unordered_map<string,vector<string>> mp;
// 防止在f1()中重复判断同一个角色
unordered_set<string>st;
struct node3
{
string s1,s2,s3;
}n3;
//角色清单的判断
bool f2(string s)
{
st.insert(s);
int fg1=0,fg2=0,fg3=0;
if(m0[s].m1.count("*")) fg1=1;
else
{
if(m0[s].m1.count(n3.s1)) fg1=1;
}
if(m0[s].m2.count("*")) fg2=1;
else
{
if(m0[s].m2.count(n3.s2)) fg2=1;
}
if(m0[s].m3.count("*")) fg3=1;
else
{
if(m0[s].m3.count(n3.s3)) fg3=1;
}
if(fg1 && fg2 && fg3) return 1;
else return 0;
}
bool f1(string s)
{
vector<string> vt1 = mp[s];
for(vector<string>::iterator it = vt1.begin(); it != vt1.end(); it++)
{
if(st.count(*it) == 0 && f2(*it) ) // 去重集合中无s用于防止重复判断
return true;
}
return false;
}
int main()
{
cin>>n>>m>>q;
//输入1,构造角色的性质结构体
for(int i=0;i<n;i++)
{
node1 n1; int nv,no,nn; string s1; cin>>s1>>nv;
for(int j=1;j<=nv;j++)
{
string s2; cin>>s2; n1.m1[s2]=1;
}
cin>>no;
for(int j=1;j<=no;j++)
{
string s2; cin>>s2; n1.m2[s2]=1;
}
cin>>nn;
if(!nn) n1.m3["*"]=1; //为空的话就说明……
else
{
for(int j=1;j<=nn;j++)
{
string s2; cin>>s2; n1.m3[s2]=1;
}
}
m0[s1]=n1; // 定义角色名称与角色性质结构体的映射关系
}
//输入2 :角色关联
for(int i=1;i<=m;i++)
{
int ns; string s1,s2,s3;
cin>>s1; // 角色关联的角色名称
cin>>ns;
for(int j=1;j<=ns;j++)
{
// 用户名和用户组名本质上都是一样的,不用区分
cin>>s2>>s3;
mp[s3].push_back(s1); // 将角色关联的用户或者用户组 和 角色关联的角色建立映射关系
// 存储了用户或者用户组所关联的角色
}
}
//输入3
for(int i=1;i<=q;i++)
{
int flag=0;
vector<string>vt; // vt中存放所该操作所允许的用户名和用户组名
string s1; // s1表示用户名
int ng; cin>>s1>>ng;
vt.push_back(s1);
while(ng--)
{
string s2; // s2表示用户组名称
cin>>s2;
vt.push_back(s2);
} // ng
cin>> n3.s1 >> n3.s2 >> n3.s3;
// 遍历用户名,根据角色关联找出所有相关的角色,再根据角色的结构体性质判断该操作是否能进行
for(auto st:vt)
{
if(mp[st].size() != 0 )
{
if( f1(st) )
{
flag=1;
break;
}
}
}
if(flag) cout<<1<<endl;
else cout<<0<<endl;
//归零
st.clear();
flag=0;
}
return 0;
}