202206-3 角色授权 100分(含注释)(两种判断方法)

#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;
}

  • 2
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值