CCF 201612-3 Privilege Query
Although I felt very annoyed when I wrote it, it was once done.
This problem is mainly in deciding how to store the permissions of each role and the roles of each user. Because the title clearly indicates that all the permissions will only appear in the P segment, the P segment data is actually indispensable to this problem. It can be dealt with directly by getline.
Originally intended to use the structure, all the permissions of each role will be treated as all attributes of a role, and all roles of each user will be treated as the same, but feel that each time to find the corresponding permissions will be iterated over, more troublesome, and finally use nested map.
Map < string, vector < Privilege > is used to map roles to permissions (it seems better to use map < string, map < string, int > later, but it is too lazy to change). Map < string, map < string, int > is used to map user names to permissions. The second one is intended to map user names to roles, but it is noticed that in query operation, only user names are needed to find permissions. Therefore, role information can be ignored directly.
When using string find function, we should pay attention to returning string::npos when we can't find it (although we know it, but we may not carefully think that the return values are true and false). Another point is that ** reference is really super useful **. Many places use simplified code by reference, but sometimes it makes mistakes when there are pointers or arrays in the structure, and we don't know why. Why?
#include<iostream>
#include<algorithm>
#include<map>
#include<string>
#include<vector>
using namespace std;
const int max_pru = 100;
struct Privilege
{
string privilege_name;
int level;
Privilege(string p, int l):privilege_name(p),level(l){}
};
map<string,vector<Privilege> > r_t_p;
map<string,map<string, int> > u_t_p;
void show_r_t_p()
{
map<string, vector<Privilege> >::iterator mit;
for(mit = r_t_p.begin(); mit != r_t_p.end(); mit++)
{
cout << mit->first << "---> ";
vector<Privilege> &v = mit->second;
for(int i = 0; i < v.size(); i++)
{
cout << v[i].privilege_name << ":" << v[i].level << " ";
}
cout << endl;
}
}
void show_u_t_p()
{
map<string, map<string, int> >::iterator it1;
for(it1=u_t_p.begin(); it1!=u_t_p.end(); it1++)
{
cout << it1->first << "----> ";
map<string, int>& m = it1->second;
map<string, int>::iterator it2;
for(it2=m.begin(); it2!=m.end(); it2++)
{
cout << it2->first << ":" << it2->second << " ";
}
cout << endl;
}
}
int main()
{
int p;
cin >> p;
getchar();
for(int i = 0; i < p; i++)
{
string priv;
getline(cin, priv);
}
int r;
cin >> r;
for(int i = 0; i < r; i++)
{
string role;
string priv;
int p_num;
cin >> role >> p_num;
for(int j = 0; j < p_num; j++)
{
cin >> priv;
if(priv.find(":")==string::npos)
{
r_t_p[role].push_back(Privilege(priv, -1));
}else
{
string pre_priv = priv.substr(0, priv.length()-2);
int level = priv[priv.length()-1]-'0';
r_t_p[role].push_back(Privilege(pre_priv, level));
}
}
}
int u;
cin >> u;
for(int i = 0; i < u; i++)
{
string user;
int r_n;
cin >> user >> r_n;
for(int j = 0; j < r_n; j++)
{
string role;
cin >> role;
vector<Privilege> &v = r_t_p[role];
for(int k = 0; k < v.size(); k++)
{
map<string, int> &m = u_t_p[user];
if(m.count(v[k].privilege_name))
{
int one = v[k].level;
int second = m[v[k].privilege_name];
m[v[k].privilege_name]= max(one, second);
}else
{
m[v[k].privilege_name] = v[k].level;
}
}
}
}
int q;
cin >> q;
for(int i = 0; i < q; i++)
{
string user;
cin >> user;
string priv;
cin >> priv;
if(!u_t_p.count(user))
cout << "false\n";
else
{
map<string, int> &m = u_t_p[user];
if(priv[priv.length()-2]==':')
{
string pre_priv = priv.substr(0, priv.length()-2);
int level = priv[priv.length()-1]-'0';
if(!m.count(pre_priv))
cout << "false\n";
else
{
if(level<=m[pre_priv])
cout << "true\n";
else
cout << "false\n";
}
}else
{
if(!m.count(priv))
cout << "false\n";
else
{
if(m[priv]==-1)
cout << "true\n";
else
{
cout << m[priv] << "\n";
}
}
}
}
}
}
Posted by rameshmrgn on Fri, 24 May 2019 15:32:51 -0700