【CCF 201612-3】权限查询

大致思路

P段是给出的基本权限,其实没有必要去处理,因为题目中告知:R段的信息一定是准确的。

②处理R段时,使用map<string, map<string, int> > roleMap

即每个Role对应一些权限,而权限的形式是:<权限名,等级>,其中等级为-1表示它是不分等级权限。

③处理U段时,保存每个User对应的角色名称,采用map<string, vector<string> > userMap

即每个User对应了一些角色名。

④处理Q段时,对于每个查询的User,找到他们对应的Role,在每个Role中查询它们的权限。

注意事项

①在处理分等级权限时,如string str = "tmp:2",权限名为string(str.begin(), str.end()-2),权限为*(str.end()-1) - '0',因为等级是0~9的一个数字

一个Role中某个权限出现多次,以最高等级为准

③合理的使用迭代器,注意非法访问的问题:如查询的User不存在,权限不存在等问题

④输出时,只需考虑true和数字的情况,其它情况(包括非法访问)一律输出false

⑤题目说明了U段的role都来自R段,但是好像并不是这样??

⑥map真好用~

C++满分代码(带注释)

#include <iostream>
#include <cstring>
#include <vector>
#include <map>
#define endl "\n"		//"\n"的效率高一些 
using namespace std;

int n,num;
string tmp,name;	//tmp一律保存权限,如tmp:3      name保存user/role的名称 

void deal_priv()	//无需处理P段,直接全部读取完就好了 
{
	cin>>n;
	cin.get();
	for(int i=0; i<n; ++i)
		getline(cin, tmp);
}

map<string, map<string, int> > roleMap;		//储存每个role对应的权限 
void deal_role()
{
	cin>>n;
	for(int i=0; i<n; ++i)
	{
		cin>>name>>num;
		for(int j=0; j<num; ++j)
		{
			cin>>tmp;
			if(tmp.find(":") != string::npos)	//有":" 则 说明是分等级权限 
				roleMap[name][string(tmp.begin(),tmp.end()-2)] = max(*(tmp.end()-1) - '0', roleMap[name][string(tmp.begin(),tmp.end()-2)]);	//取权限等级的较大者 
			else roleMap[name][tmp] = -1;		//-1表示不分等级权限 
		}
	}
}

map<string, vector<string> > userMap;		//保存每个user对应的roles 
void deal_user()
{
	cin>>n;
	for(int i=0; i<n; ++i)
	{
		cin>>name>>num;
		for(int j=0; j<num; ++j)
		{
			cin>>tmp;
			userMap[name].push_back(tmp);
		}
	}
}

void deal_a_query()			//处理每个查询 
{
	int imax;
	cin>>name>>tmp;
	map<string, vector<string> >::iterator user_map_it = userMap.find(name);		//指向某个特定的user 
	if(user_map_it == userMap.end())		//若user不存在,false 
	{
		cout<<"false"<<endl;
		return;
	}

	map<string, map<string, int> >::iterator role_map_it;
	if(tmp.find(":") == string::npos)	//不分等级的查询 
	{
		imax = -10; 
		for(vector<string>::iterator p = user_map_it->second.begin(); p != user_map_it->second.end(); ++p)	//每个user对应的role 
		{
			role_map_it = roleMap.find(*p);
			if(role_map_it == roleMap.end()) continue;
			for(map<string, int>::iterator q = role_map_it->second.begin(); q != role_map_it->second.end(); ++q)	//每个role对应的权限 
			{
				if(q->first == tmp)
				{
					if(q->second == -1)		//若该权限不分等级,则输出true 
					{
						cout<<"true"<<endl;
						return;
					}
					else imax = max(imax, q->second); //否则更新当前该权限的最大等级 
				}
			}
		}
		if(imax != -10)		//输出最大等级 
		{
			cout<<imax<<endl;
			return;
		}
	}
	else
	{
		string pri(tmp.begin(),tmp.end()-2);
		int rank = *(tmp.end()-1) - '0';

		for(vector<string>::iterator p = user_map_it->second.begin(); p != user_map_it->second.end(); ++p)
		{
			role_map_it = roleMap.find(*p);
			if(role_map_it == roleMap.end()) continue;
			for(map<string, int>::iterator q = role_map_it->second.begin(); q != role_map_it->second.end(); ++q)
				if(q->first == pri && q->second >= rank)	//查询等级小于等于user等级 
				{
					cout<<"true"<<endl;
					return;
				}
		}
	}
	cout<<"false"<<endl;
}

int main()
{
	ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);	//关同步,加快输入输出 

	deal_priv();
	deal_role();
	deal_user();

	cin>>n;
	for(int i=0; i<n; ++i)
		deal_a_query();

	return 0;
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值