CSP第九次认证-3 权限查询

详细注释都在代码里了

代码中相关的知识:

#include <iostream>
#include <string>
#include <algorithm>
#include <set>
#include <unordered_map>
//本道题三种关系依次嵌套,在想好如何存储之后便可以开始写了
//省略了person中role的存储,在读入中将role转化为对应的权限,所以person里存的也是权限
using namespace std;
struct P
{
    string pname;
    mutable int level;//因为要修改set中的值,所以要把level前面加上mutable
    P(string str)//结构体的初始化
    {
        int pos = str.find(':'); //如果没有冒号说明没有等级权限
        if (pos == -1)pname = str, level = -1;//-1表示无等级权限
        else
        {
            pname = str.substr(0, pos);//将str中从第0个字符开始,长度是五的字符串copy给name,详细用法见下图
            level = stoi(str.substr(pos + 1,1));//stoi将string转化为int
        }
    }
    bool operator<(const P& W)const//因为用了set存储结构体,所以需要运算符重载
    {
        return pname < W.pname;
    }
};
unordered_map<string, set<P>> person, role;
int main()
{
    int n;
    string name, right;
    cin >> n;
    while (n--)cin >> name;
    cin >> n;//role的读入
    while (n--)
    {
        cin >> name;
        int cnt;
        cin >> cnt;
        set<P>& r = role[name];
        while (cnt--)
        {
            cin >> right;
            P tmp(right);//让right符合规范
            if (tmp.level == -1)r.insert(tmp);//无等级权限
            else
            {
                if (!r.count(tmp))r.insert(tmp);//之前没有这个权限
                else
                {
                    auto t = r.find(tmp);//找到已经存储的权限
                    t->level = max(t->level, tmp.level);//取最高等级的权限
                }
            }
        }
    }
    cin >> n;//person的读入
        while (n--)
        {
            cin >> name;
            int cnt;
            cin >> cnt;
            set<P>& p = person[name];
            while (cnt--)
            {
                string str;
                cin >> str;//角色role
                for (auto& tmp : role[str])//枚举角色 role[str]是一个权限集合set<P>
                {
                    if (tmp.level == -1)p.insert(tmp);//无等级权限
                    else
                    {
                        if (!p.count(tmp))p.insert(tmp);//之前没有这个权限
                        else
                        {
                            auto t = p.find(tmp);//找到已经存储的权限
                            t->level = max(t->level, tmp.level);//取最高等级的权限
                        }
                    }
                }
            }
        }
    cin >> n; //读入所有的询问
    while (n--)
    {
        string username, pr; //读入用户名和权限
        cin >> username >> pr;
        P t(pr); //将权限变成结构体
        set<P>& p = person[username];
        if (!p.count(t)) puts("false");
        else
        {
            auto it = p.find(t);
            if (t.level != -1)
            {
                if (it->level >= t.level) puts("true");
                else puts("false");
            }
            else
            {
                if (it->level == -1) puts("true"); //不分等级权限,有该权限
                else cout << it->level << endl; //分等级权限,但是不指定查询等级,输出该用户拥有的最高等级权限
            }
        }
    }
    return 0;
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值