1 solutions
-
1
阅读理解大模拟,没什么好说的,我主要讲一下自己处理这种问题的设计思路和习惯。
首先,从常数设计的角度考虑,STL 嵌套多了会特别慢,因此可以将角色和用户都分别设计一个
unordered_map<string, int>
类,将每一个字符串映射到静态数组的下标上,实际数据库的信息用静态数组来存储就好了。比如下面存储角色的时候,外层是数组,里面再用哈希
unordered_set
去存储op
(操作清单),res_cat
(资源种类清单),res_name
(资源名称清单)然后角色内部的操作权限写一个成员函数即可,遵循判断过程的 4 个条件去写就行了。
const int N = 200010; // character int chara_cnt; std::unordered_map<std::string, int> chara; const std::string all = "*"; struct chara_list { std::unordered_set<std::string> op_list; std::unordered_set<std::string> res_cat_list; std::unordered_set<std::string> res_name_list; void add_op(const std::string& s) { op_list.insert(s); } void add_res_cat(const std::string& s) { res_cat_list.insert(s); } void add_res_name(const std::string& s) { res_name_list.insert(s); } bool access(const std::string& op, const std::string& res_cat, const std::string& res_name) { if (!(op_list.count(all) || op_list.count(op))) return 0; if (!(res_cat_list.count(all) || res_cat_list.count(res_cat))) return 0; if (!(res_name_list.empty() || res_name_list.count(res_name))) return 0; return 1; } }; chara_list ch_list[N];
那么在题面最开始读取 个角色的时候,就可以这样去处理:
std::ios::sync_with_stdio(0); std::cin.tie(0), std::cout.tie(0); std::cin >> n >> m >> q; std::string s; // input character while (n--) { std::cin >> s; // name if (!chara.count(s)) // 如果是头一次出现的角色,则新建 id 表示对应下标的映射 chara[s] = ++chara_cnt; int idx = chara[s]; int x = 0; std::cin >> x; while (x--) std::cin >> s, ch_list[idx].add_op(s); std::cin >> x; while (x--) std::cin >> s, ch_list[idx].add_res_cat(s); std::cin >> x; while (x--) std::cin >> s, ch_list[idx].add_res_name(s); }
接下来读取角色关联则可以使用类似的方式,读入了字符串之后,先映射到对应的数字。然后对于用户和用户组,同样使用
string
到int
映射的unordered_map
来维护用户以及用户组即可。// user int single_user_cnt; std::unordered_map<std::string, int> single_user; // user group int group_cnt; std::unordered_map<std::string, int> group_user; struct user_list { std::vector<int> ch_list_idx; void add_chara(int idx) { ch_list_idx.push_back(idx); } };
单独用户和用户组都是记录若干个角色的,以此来表示角色关联的关系,因此在输入角色关联时,把他们加入关系组即可。
while (m--) { std::cin >> s; int idx = chara[s]; std::string cat, name; int x = 0; std::cin >> x; while (x--) { std::cin >> cat >> name; if (cat == "u") { if (!single_user.count(name)) single_user[name] = ++single_user_cnt; int u_idx = single_user[name]; single_list[u_idx].add_chara(idx); } else { if (!group_user.count(name)) group_user[name] = ++group_cnt; int u_idx = group_user[name]; group_list[u_idx].add_chara(idx); } } }
而用户判断操作的话,则参照用户的判断流程,需要传入单个用户对应的 id,输入的所有用户组,以及对应到每个角色的操作。
bool judge(int user, const std::vector<int>& group, const std::string& op, const std::string& cat, const std::string& name) { if (user) { for (size_t i = 0; i < single_list[user].ch_list_idx.size(); ++i) { int idx = single_list[user].ch_list_idx[i]; if (ch_list[idx].access(op, cat, name)) return 1; } } for (size_t i = 0; i < group.size(); ++i) { for (size_t j = 0; j < group_list[group[i]].ch_list_idx.size(); ++j) { int idx = group_list[group[i]].ch_list_idx[j]; if (ch_list[idx].access(op, cat, name)) return 1; } } return 0; }
因此整体的代码如下,需要分模块慢慢进行理解。
#include <iostream> #include <string> #include <vector> #include <unordered_map> #include <unordered_set> const int N = 200010; int n, m, q; // character int chara_cnt; std::unordered_map<std::string, int> chara; const std::string all = "*"; struct chara_list { std::unordered_set<std::string> op_list; std::unordered_set<std::string> res_cat_list; std::unordered_set<std::string> res_name_list; void add_op(const std::string& s) { op_list.insert(s); } void add_res_cat(const std::string& s) { res_cat_list.insert(s); } void add_res_name(const std::string& s) { res_name_list.insert(s); } bool access(const std::string& op, const std::string& res_cat, const std::string& res_name) { if (!(op_list.count(all) || op_list.count(op))) return 0; if (!(res_cat_list.count(all) || res_cat_list.count(res_cat))) return 0; if (!(res_name_list.empty() || res_name_list.count(res_name))) return 0; return 1; } }; chara_list ch_list[N]; // user int single_user_cnt; std::unordered_map<std::string, int> single_user; // user group int group_cnt; std::unordered_map<std::string, int> group_user; struct user_list { std::vector<int> ch_list_idx; void add_chara(int idx) { ch_list_idx.push_back(idx); } }; user_list single_list[N], group_list[N]; bool judge(int user, const std::vector<int>& group, const std::string& op, const std::string& cat, const std::string& name) { if (user) { for (size_t i = 0; i < single_list[user].ch_list_idx.size(); ++i) { int idx = single_list[user].ch_list_idx[i]; if (ch_list[idx].access(op, cat, name)) return 1; } } for (size_t i = 0; i < group.size(); ++i) { for (size_t j = 0; j < group_list[group[i]].ch_list_idx.size(); ++j) { int idx = group_list[group[i]].ch_list_idx[j]; if (ch_list[idx].access(op, cat, name)) return 1; } } return 0; } int main() { std::ios::sync_with_stdio(0); std::cin.tie(0), std::cout.tie(0); std::cin >> n >> m >> q; std::string s; // input character while (n--) { std::cin >> s; // name if (!chara.count(s)) chara[s] = ++chara_cnt; int idx = chara[s]; int x = 0; std::cin >> x; while (x--) std::cin >> s, ch_list[idx].add_op(s); std::cin >> x; while (x--) std::cin >> s, ch_list[idx].add_res_cat(s); std::cin >> x; while (x--) std::cin >> s, ch_list[idx].add_res_name(s); } while (m--) { std::cin >> s; int idx = chara[s]; std::string cat, name; int x = 0; std::cin >> x; while (x--) { std::cin >> cat >> name; if (cat == "u") { if (!single_user.count(name)) single_user[name] = ++single_user_cnt; int u_idx = single_user[name]; single_list[u_idx].add_chara(idx); } else { if (!group_user.count(name)) group_user[name] = ++group_cnt; int u_idx = group_user[name]; group_list[u_idx].add_chara(idx); } } } int user = 0; int gcnt; std::vector<int> group; std::string _op, reslist, resname; while (q--) { std::cin >> s; user = single_user[s]; // std::cout << "add user " << user << '\n'; group.clear(); std::cin >> gcnt; while (gcnt--) { std::cin >> s; if (group_user.count(s)) group.push_back(group_user[s]); //, std::cout << "add group " << group_user[s] << '\n'; } std::cin >> _op >> reslist >> resname; std::cout << judge(user, group, _op, reslist, resname) << '\n'; } }
- 1
Information
- ID
- 32
- Time
- 5000ms
- Memory
- 512MiB
- Difficulty
- 3
- Tags
- # Submissions
- 18
- Accepted
- 3
- Uploaded By