版权声明: https://blog.csdn.net/leelitian3/article/details/82421797
大致思路
①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;
}