试题编号: 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();
}