CSP202206-3角色授权

CSP202206-3角色授权

题目

在这里插入图片描述
在这里插入图片描述

思路

无脑建立映射关系即可

题解

#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;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值