201612-3 权限查询 100分 109ms

点击前往试题目录:https://blog.csdn.net/best335/article/details/99550556
在这里插入图片描述

#include<iostream>
#include<map>
#include<set>
#include<cstring>
using namespace std;
int main(){
	int p,r,u,q;
	string s;
	map<string,int>P;//权限名 等级
	map<pair<string,string>,int>M;//角色 权限名
	map<string,set<string> >U;//用户 角色
	cin>>p;
	for(int i=0;i<p;++i){
		cin>>s;
		int j=0,nj=s.size();
		while(j<nj&&s[j]!=':') ++j;
		P[s.substr(0,j)]= j<nj?(s[j+1]-'0'):-1;
	}
	cin>>r,cin.get();
	for(int i=0,_s;i<r;++i){
		cin>>s>>_s;
		for(int j=0;j<_s;++j){
			string _r;
			cin>>_r;
			int k=0,nk=_r.size();
			while(k<nk&&_r[k]!=':')++k;
			pair<string,string> p(s,_r.substr(0,k));
			if(M.find(p)==M.end()) M[p]=nk==k?-1:(_r[k+1]-'0');
			else M[p]=max(M[p],nk==k?-1:(_r[k+1]-'0'));//取最大的权限等级
		}
	}
	cin>>u;
	for(int i=0,t;i<u;++i){
		cin>>s>>t;
		for(int j=0;j<t;++j){
			string _r;
			cin>>_r;
			U[s].insert(_r);
		}
	}
	cin>>q;
	for(int i=0;i<q;++i){
		string _s;
		cin>>s>>_s;
		int j=0,nj=_s.size(),f=0;
		while(j<nj&&_s[j]!=':')++j;
		string name=_s.substr(0,j);
		if(P.find(name)==P.end()){//如果没有这个权限种类
			cout<<boolalpha<<false<<endl;
			continue;
		}
		int level=j==nj?-1:(_s[j+1]-'0'),max_level=P[name],q_level=-1;
		if(level>max_level){//如果查询的超过对应权限种类的权限等级
			cout<<boolalpha<<false<<endl;
			continue;
		}
		set<string>& UR=U[s];//开始遍历该查询用户的所有角色
		for(set<string>::const_iterator it=UR.begin();it!=UR.end()&&f<1;++it){
			map<pair<string,string>,int>::const_iterator itM=M.find(pair<string,string>(*it,name));
			if(itM!=M.end()){
				if(level==-1){
					if(itM->second==-1)//不分等级权限的查询
						cout<<boolalpha<<true<<endl,f=1;
					else//分等级权限的不带等级查询
						q_level=max(itM->second,q_level),f=-1;
				}
				else if(itM->second>=level)//分等级权限的带等级查询
					cout<<boolalpha<<true<<endl,f=1;
			}
		}
		if(f==0)//遍历用户角色查询不到
			cout<<boolalpha<<false<<endl;
		if(f==-1)//分等级权限的不带等级查询
			cout<<min(max_level,q_level)<<endl;
	}
	return 0;
}
  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值