这个题目和上一年的第三题十分相似,感觉是同一类型的题目,主要就是考察能否熟练的运用STL容器
首先,通读题目,理清思路,再动手写,这个很关键,还没理清楚,就开始写,逻辑上会有很多漏洞,难以调试
题目的主要意思就是
角色有名字,操作,资源等等
每一个角色有相关的拥有者或拥有组
然后给你一个人,以及需要进行的操作,问你这个人能不能执行这个操作
然后就可以根据题目细节,思考如何设计数据结构了
例如:
判断一个用户能否执行某个操作的过程,首先需要将这个人所关联的角色找出来
由于一个人可能与多个角色相关联
所以可以设计一个 unordered_map
判断一个角色是否有xx操作,xx资源种类,xx资源
可以设计一个结构体,并且这个结构体里有三个unordered_map
每一个角色都设计成结构体了,如何快速查找某个角色?
再设计一个unordered_map
等等
将这些结构体设计出来之后
再根据题目中判断的依据,一步一步模拟就可以了(不是很难,详情见代码)
然后可能只有70+
还需要优化一下
如果最后一个查询循环里,有很多循环,尝试着进行删减或预处理,减少循环,因为可以算一下,时间复杂度可能会超
还有一个优化的点就是,这个题目的输入数据量不小,可以自己算一下,所以使用ios::sync_with_stdio(false);,时间就得到优化
得到满分啦
其实这个题目思路理清楚了,并熟练运用stl容器的话,真的不是特别难,简单的模拟就可以得70+,再小优化一下,就可以拿满分
#include
#include
#include
#include
using namespace std;
const int N = 510;
map<string, vector <string> > rolecon; //记录该用户与哪些角色相匹配
map<string, int> rid; //记录角色所对应的结构体下标
struct role
{
string name;
map <string, int> opset;
map <string, int> rskind;
map <string, int> rsname;
}R[N];
bool check (string rolename, string opname, string rskd, string rsne)
{
bool flag = true;
int id = rid[rolename];
if ((R[id].opset.count("*") == 0) && (R[id].opset.count(opname) == 0)) return false;
if ((R[id].rskind.count("*") == 0) && (R[id].rskind.count(rskd) == 0)) return false;
if ((R[id].rsname.size() != 0) && (R[id].rsname.count(rsne) == 0)) return false;
return true;
}
int main()
{
ios::sync_with_stdio(false);
int n, m, q;
cin >> n >> m >> q;
//保存角色内容
for (int i = 0; i < n; i ++)
{
string name;
cin >> name;
R[i].name = name;
rid[name] = i;
int opnum;
cin >> opnum;
for (int j = 0; j < opnum; j ++)
{
string t;
cin >> t;
R[i].opset[t] = 1;
}
int rk;
cin >> rk;
for (int j = 0; j < rk; j ++)
{
string t;
cin >> t;
R[i].rskind[t] = 1;
}
int rn;
cin >> rn;
for (int j = 0; j < rn; j ++)
{
string t;
cin >> t;
R[i].rsname[t] = 1;
}
}
//存储用户或组分别拥有哪些角色
for (int i = 0; i < m; i ++)
{
string rname;
cin >> rname;
int rcnt;
cin >> rcnt;
for (int j = 0; j < rcnt; j ++)
{
string kind, name;
cin >> kind >> name;
rolecon[name].push_back(rname);
}
}
while (q --)
{
string pname;
cin >> pname;
int zulen;
cin >> zulen;
vector <string> yongzu;
for (int i = 0; i < zulen; i ++)
{
string t;
cin >> t;
yongzu.push_back(t);
}
string opname, sk, sn;
cin >> opname >> sk >> sn;
bool flag = false;
for (int i = 0; i < rolecon[pname].size(); i ++)
{
if (check(rolecon[pname][i], opname, sk, sn))
{
flag = true;
break;
}
}
if (flag)
{
cout << 1 << endl;
continue;
}
for (int i = 0; i < yongzu.size(); i ++)
{
string zname = yongzu[i];
for (int j = 0; j < rolecon[zname].size(); j ++)
{
if (check(rolecon[zname][j], opname, sk, sn))
{
flag = true;
break;
}
}
if (flag) break;
}
if (flag) cout << 1 << endl;
else cout << 0 << endl;
}
return 0;
}