思路应该没问题,调了一下午还是90分,有一个测试点超时了。
#include<bits/stdc++.h>
#include<vector>
using namespace std;
class role{
public:
vector<string> operation;
vector<string> resource;
vector<string> resource_name;
};
class group{
public:
set<string> role;
};
class user{
public:
set<string> role;
set<string> group;
};
map<string,role> r;
map<string,group> g;
map<string,user> u;
int main(){
std::ios::sync_with_stdio(false);//加速用
int n,m,q;
cin>>n>>m>>q;
for(int i=0;i<n;i++){
role temp;
string name;
cin>>name;
int operation_num;
cin>>operation_num;
for(int j=0;j<operation_num;j++){
string operate;
cin>>operate;
temp.operation.push_back(operate);
}
int resource_num;
cin>>resource_num;
for(int j=0;j<resource_num;j++){
string resource;
cin>>resource;
temp.resource.push_back(resource);
}
int resource_name_num;
cin>>resource_name_num;
for(int j=0;j<resource_name_num;j++){
string resource_name;
cin>>resource_name;
temp.resource_name.push_back(resource_name);
}
r[name]=temp;
}
for(int i=0;i<m;i++){
string role_name;
cin>>role_name;
int object_num;
cin>>object_num;
for(int j=0;j<object_num;j++){
char type;
cin>>type;
string uname;
cin>>uname;
if(type=='g'){
g[uname].role.insert(role_name);
}
if(type=='u'){
u[uname].role.insert(role_name);
}
}
}
bool examine(const string& uname,const string& operate,const string& resource,const string& resource_name);
for(int i=0;i<q;i++){
string uname;
cin>>uname;
int gnum;
cin>>gnum;
for(int j=0;j<gnum;j++){
string gname;
cin>>gname;
u[uname].group.insert(gname);
}
string operation;
string resource;
string resource_name;
cin>>operation>>resource>>resource_name;
if(examine(uname,operation,resource,resource_name)){
cout<<"1"<<"\n";
}
else{
cout<<"0"<<"\n";
}
u[uname].group.clear();
}
}
bool examine(const string& uname,const string& operate,const string& resource,const string& resource_name){
for (auto role : u[uname].role) {
auto& currentRole = r[role];
auto opIter = std::find(currentRole.operation.begin(), currentRole.operation.end(), operate);
auto resIter = std::find(currentRole.resource.begin(), currentRole.resource.end(), resource);
auto resNameIter = std::find(currentRole.resource_name.begin(), currentRole.resource_name.end(), resource_name);//超时就想着这样来加速,可惜没成功
if (opIter != currentRole.operation.end() || std::find(currentRole.operation.begin(), currentRole.operation.end(), "*") != currentRole.operation.end()) {
if (resIter != currentRole.resource.end() || std::find(currentRole.resource.begin(), currentRole.resource.end(), "*") != currentRole.resource.end()) {
if (resNameIter != currentRole.resource_name.end() || currentRole.resource_name.empty()) {
return true;
}
}
}
}
for(const auto& group:u[uname].group){
for(auto role:g[group].role) {
auto& currentRole = r[role];
auto opIter = std::find(currentRole.operation.begin(), currentRole.operation.end(), operate);
auto resIter = std::find(currentRole.resource.begin(), currentRole.resource.end(), resource);
auto resNameIter = std::find(currentRole.resource_name.begin(), currentRole.resource_name.end(), resource_name);
if (opIter != currentRole.operation.end() || std::find(currentRole.operation.begin(), currentRole.operation.end(), "*") != currentRole.operation.end()) {
if (resIter != currentRole.resource.end() || std::find(currentRole.resource.begin(), currentRole.resource.end(), "*") != currentRole.resource.end()) {
if (resNameIter != currentRole.resource_name.end() || currentRole.resource_name.empty()) {
return true;
}
}
}
}
}
return false;
}