【CCFCSP】201612-3 权限查询

试题编号: 201612-3
试题名称: 权限查询
时间限制: 1.0s
内存限制: 256.0MB

//这道题用STL拿了90,改成用结构体拿了满分
首先要理清题意,用户可以拥有多个角色,其中不同的权限可以有名称不同的权限,也可能拥有名称相同,等级不同的权限。
考虑使用结构体保存权限,角色,用户的信息。权限是角色结构体中的属性,表示某角色拥有这个权限,同时记录其拥有的角色的数量,方便之后查询。角色是用户的属性,表示用户拥有这个角色,同样的,记录用户拥有的角色的数量。
在查询时,每次查询用户拥有的角色,再查询这个角色拥有的权限。(想象成嵌套的for循环)。
读取的输入可能是不分等级权限或带数字的部分的等级权限,需要注意。
在处理查询时,要考虑的情况有:查询是包含等级的分等级权限,不包含等级的分等级权限,不包含等级的不分等级权限。(不会出现查询含等级的不分等级权限的情况)。同时还要判断查询的用户和权限是否存在。

//保存权限信息
struct Privilege {
    string name;
    int level;
}privilege[110];
//保存角色信息
struct Role {
    string name;
    Privilege privi[11];
    int privilege_num;
}role[110];
//保存用户信息
struct User {
    string name;
    Role role[11];
    int rolenum;
}usr[110];
int p, u, r, q, pos;
string s;
//用于查找privilege的下标
int findPrivi(string str) {
    for (int i = 0; i < 100; i++) {
        if (privilege[i].name == str)
            return i;
    }
    return -1;
}
//用于查找role的下标
int findRole(string str) {
    for (int i = 0; i < 100; i++) {
        if (role[i].name == str)
            return i;
    }
    return -1;
}
//用于查找usr的下标
int findUser(string str) {
    for (int i = 0; i<100; i++) {
        if (usr[i].name == str) return i;
    }
    return -1;
}
//权限读入
void readPrivi() {
    for (int i = 0; i < p; i++) {
        cin >> s;
        if (s.find(':', 0) == s.npos) {
            privilege[i].level = -1;//level等于-1代表不分等级权限
            privilege[i].name = s;
        }
        else {
            pos = s.find(':', 0);
            privilege[i].name = s.substr(0, pos);
            privilege[i].level = s[s.length() - 1] - '0';
        }
    }
}
//角色读入
void readRole() {
    for (int i = 0; i < r; i++) {
        cin >> role[i].name;
        cin >> role[i].privilege_num;
        for (int j = 0; j < role[i].privilege_num; j++) {
            cin >> s;
            if (s.find(':', 0) == s.npos) {
                role[i].privi[j].level = -1;
                role[i].privi[j].name = s;
            }
            else {
                pos = s.find(':', 0);
                role[i].privi[j].name = s.substr(0, pos);
                role[i].privi[j].level = s[s.length() - 1] - '0';
            }
        }
    }
}
//角色读入
void readUser() {
    for (int i = 0; i < u; i++) {
        cin >> usr[i].name;
        cin >> usr[i].rolenum;
        for (int j = 0; j < usr[i].rolenum; j++) {
            cin >> s;
            usr[i].role[j] = role[findRole(s)];
        }
    }
}
void solve() {
    string tmp;
    while (q--) {
        int t_level = -1;//保存询问中的权限等级
        cin >> s >> tmp;
        int t_usr = findUser(s);
        if (tmp.find(':', 0) != tmp.npos) {
            pos = tmp.find(':', 0);
            t_level = tmp[tmp.length() - 1] - '0';
            tmp = tmp.substr(0, pos);
        }
        int t_privi = findPrivi(tmp);
        //如果被查询的权限名或用户名不存在,直接输出false
        if (t_usr == -1 || t_privi == -1) {
            cout << "false" << endl;
            continue;
        }
        //询问中不包含权限等级的情况
        if (t_level == -1) {
            //询问的是分等级权限
            if (privilege[t_privi].level != -1) {
                int ans = -1;
                for (int j = 0; j<usr[t_usr].rolenum; j++) {
                    for (int k = 0; k<usr[t_usr].role[j].privilege_num; k++) {
                        if (usr[t_usr].role[j].privi[k].name == tmp) {
                            ans = max(ans, usr[t_usr].role[j].privi[k].level);
                        }
                    }
                }
                if (ans == -1) {
                    cout << "false" << endl;
                }
                else
                    cout << ans << endl;
            }
            //询问的是不分等级权限
            else {
                int ans = -1;
                for (int j = 0; j<usr[t_usr].rolenum; j++) {
                    for (int k = 0; k<usr[t_usr].role[j].privilege_num; k++) {
                        if (usr[t_usr].role[j].privi[k].name == tmp) {
                            ans = 1;//代表用户拥有该权限
                        }
                    }
                }
                if (ans == -1) {
                    cout << "false" << endl;
                }
                else
                    cout << "true" << endl;
            }
        }
        //询问中包含权限等级的情况
        else {
            int ans = -1;
            for (int j = 0; j<usr[t_usr].rolenum; j++) {
                for (int k = 0; k<usr[t_usr].role[j].privilege_num; k++) {
                    if (usr[t_usr].role[j].privi[k].name == tmp) {
                        //遍历用户拥有的权限,找到用户拥有的被查询权限等级的最大值
                        ans = max(ans, usr[t_usr].role[j].privi[k].level);
                    }
                }
            }
            //用户拥有的权限比查询的高
            if (ans >= t_level) {
                cout << "true" << endl;
            }
            else
                cout << "false" << endl;
        }
    }
}
int main() {
    string s;
    cin >> p;
    readPrivi();
    cin >> r;
    readRole();
    cin >> u;
    readUser();
    cin >> q;
    solve();
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值