csp:202206-3:角色授权()

这一题我认为,难就难在处理输入和定义数据结构。只要数据结构定义对了,那么后面的操作就很简单了。附上正确代码:

#include<iostream>
#include<string>
#include<unordered_set>
#include<unordered_map>
#include<vector>
using namespace std;

int n,m,q;

struct role{
  unordered_set<string>ops;
  unordered_set<string>source_class;
  unordered_set<string>source_names;
};

struct group{
  vector<string> roles;
};

struct user{
  vector<string> roles;
};

unordered_map<string, role> role_map;
unordered_map<string, group> group_map;
unordered_map<string, user> user_map;

bool check_role(string role,string op,string sclazz,string name){
  return (role_map[role].ops.count(op)>0||role_map[role].ops.count("*")>0)
    &&(role_map[role].source_class.count(sclazz)>0||role_map[role].source_class.count("*")>0)
    &&(role_map[role].source_names.size()==0||role_map[role].source_names.count(name)>0);
}

int main(){
  ios::sync_with_stdio(0);
//  cin.tie(0);
//  cout.tie(0);
  cin>>n>>m>>q;
  int nv,no,nn,ns;
  string tmp,role_name;
  for(int i=0;i<n;i++){
//    cout<<"role\n";
    cin>>role_name;
    cin>>nv;
    for(int j=0;j<nv;j++){
      cin>>tmp;
      role_map[role_name].ops.emplace(tmp);
    }
    cin>>no;
    for(int j=0;j<no;j++){
      cin>>tmp;
      role_map[role_name].source_class.emplace(tmp);
    }
    cin>>nn;
    for(int j=0;j<nn;j++){
      cin>>tmp;
      role_map[role_name].source_names.emplace(tmp);
    }
  }
  for(int i=0;i<m;i++){
//    cout<<"role_relate\n";
    cin>>role_name;
    cin>>ns;
    char type;
    for(int j=0;j<ns;j++){
      cin>>type;
      cin>>tmp;
      if(type=='u'){
        user_map[tmp].roles.push_back(role_name); 
      }else if(type=='g'){
        group_map[tmp].roles.push_back(role_name);
      }
    }
  }
  string user_name;
  int ng;
  string op,sclazz,sname;
  for(int i=0;i<q;i++){
//    cout<<"query\n";
    cin>>user_name;
    cin>>ng;
    vector<string> groups(ng);
    for(int j=0;j<ng;j++){
      cin>>tmp;
      groups[j]=tmp;
    } 
    cin>>op>>sclazz>>sname;
    bool flag=0;
    // check user
    if(user_map.count(user_name)>0){
      for(string r:user_map[user_name].roles){
        if(check_role(r,op,sclazz,sname)){
          cout<<"1\n";
          flag=1;
          break;
        }
      }
    }
    if(flag) continue;
    // check group
    for(int j=0;j<ng;j++){
      for(string r:group_map[groups[j]].roles){
        if(check_role(r,op,sclazz,sname)){
          cout<<"1\n";
          flag=1;
          break;
        }
      }
      if(flag) break;
    }
    if(!flag){
      cout<<"0\n";
    }
  }
  return 0;
} 
————————

这一题我认为,难就难在处理输入和定义数据结构。只要数据结构定义对了,那么后面的操作就很简单了。附上正确代码:

#include<iostream>
#include<string>
#include<unordered_set>
#include<unordered_map>
#include<vector>
using namespace std;

int n,m,q;

struct role{
  unordered_set<string>ops;
  unordered_set<string>source_class;
  unordered_set<string>source_names;
};

struct group{
  vector<string> roles;
};

struct user{
  vector<string> roles;
};

unordered_map<string, role> role_map;
unordered_map<string, group> group_map;
unordered_map<string, user> user_map;

bool check_role(string role,string op,string sclazz,string name){
  return (role_map[role].ops.count(op)>0||role_map[role].ops.count("*")>0)
    &&(role_map[role].source_class.count(sclazz)>0||role_map[role].source_class.count("*")>0)
    &&(role_map[role].source_names.size()==0||role_map[role].source_names.count(name)>0);
}

int main(){
  ios::sync_with_stdio(0);
//  cin.tie(0);
//  cout.tie(0);
  cin>>n>>m>>q;
  int nv,no,nn,ns;
  string tmp,role_name;
  for(int i=0;i<n;i++){
//    cout<<"role\n";
    cin>>role_name;
    cin>>nv;
    for(int j=0;j<nv;j++){
      cin>>tmp;
      role_map[role_name].ops.emplace(tmp);
    }
    cin>>no;
    for(int j=0;j<no;j++){
      cin>>tmp;
      role_map[role_name].source_class.emplace(tmp);
    }
    cin>>nn;
    for(int j=0;j<nn;j++){
      cin>>tmp;
      role_map[role_name].source_names.emplace(tmp);
    }
  }
  for(int i=0;i<m;i++){
//    cout<<"role_relate\n";
    cin>>role_name;
    cin>>ns;
    char type;
    for(int j=0;j<ns;j++){
      cin>>type;
      cin>>tmp;
      if(type=='u'){
        user_map[tmp].roles.push_back(role_name); 
      }else if(type=='g'){
        group_map[tmp].roles.push_back(role_name);
      }
    }
  }
  string user_name;
  int ng;
  string op,sclazz,sname;
  for(int i=0;i<q;i++){
//    cout<<"query\n";
    cin>>user_name;
    cin>>ng;
    vector<string> groups(ng);
    for(int j=0;j<ng;j++){
      cin>>tmp;
      groups[j]=tmp;
    } 
    cin>>op>>sclazz>>sname;
    bool flag=0;
    // check user
    if(user_map.count(user_name)>0){
      for(string r:user_map[user_name].roles){
        if(check_role(r,op,sclazz,sname)){
          cout<<"1\n";
          flag=1;
          break;
        }
      }
    }
    if(flag) continue;
    // check group
    for(int j=0;j<ng;j++){
      for(string r:group_map[groups[j]].roles){
        if(check_role(r,op,sclazz,sname)){
          cout<<"1\n";
          flag=1;
          break;
        }
      }
      if(flag) break;
    }
    if(!flag){
      cout<<"0\n";
    }
  }
  return 0;
}