CCF CSP 201612-3 权限查询

样例输入

3
crm:2
git:3
game
4
hr 1 crm:2
it 3 crm:1 git:1 game
dev 2 git:3 game
qa 1 git:2
3
alice 1 hr
bob 2 it qa
charlie 1 dev
9
alice game
alice crm:2
alice git:0
bob git
bob poweroff
charlie game
charlie crm
charlie git:3
malice game

样例输出

false
true
false
2
false
true
false
true
false

直接用多个map去对应过去名字和权限以及等级
思路蛮简单的,就注意一些细节,比如多个角色
有相同的权限取最高,权限存不存在啊啥的

#include<bits/stdc++.h>
#include<string.h>
using namespace std;
#define rep(i,j,k) for(LL i=(j); i<(k); ++i)
#define pb push_back
#define PII pair<LL,LL>
#define PLL pair<long long, long long>
#define ini(a,j) memset(a,j,sizeof a)
#define rrep(i,j,k) for(LL i=j; i>=k; --i)
#define fi first
#define se second
#define LL long long
#define beg begin()
#define end end()
#define all(x) x.begin(),x.end()
const LL mod= 1e9+7;
const unsigned int N = 1e5+10;

// all 存的是一个职业对应的权限等级
// ans 存储人对应的权限
map<pair<string, string>, int> all, ans;

//p_info存权限是否的有等级的
map<string, int> p_info;

// 对于一个词
// 有带等级的直接先升级两级,防止冲突
// 没有等级的直接给1,防止对0无法判断
pair<string, int> split(string s){   //分词函数
	string name="";
	int j=0;
	int ma = 0;
	if(isdigit(s.back())){
		while(s[j]!=':'){
			name += s[j];
			++j;
		}
		++j;
		while(j<s.length())
			ma = ma*10+s[j++]-'0';
		ma += 2;
	}else{
		name = s;
		ma = 1;
	}
	return make_pair(name, ma);
}


void solve(string name, string quer){
	auto que = split(quer);

	//先去map中查这个人的权限是什么等级
	int res = ans[make_pair(name, que.fi)];
	int type = p_info[que.fi];
	if(!res){
		cout<<"false"<<endl;
		return;
	}
	if(que.se==1){ //不带数字的查询
		if(type==1){
			cout<<(res==0 ? "false":"true")<<endl;
		}else{
			cout<<res-2<<endl;
		}
	}else{
		cout<<(que.se<=res? "true":"false")<<endl;
	}

}
int main(int argc, char const *argv[])
{
	// #define DEBUG
    	#ifdef DEBUG
		freopen("1.dat","r",stdin);
	#endif
	ios::sync_with_stdio(false);
	cin.tie(0);
	cout.tie(0);
	int pnum;
	cin>>pnum;
	
	string info;
	rep(i,0,pnum){
		cin>>info;
		auto info_m = split(info);
		p_info[info_m.fi]=info_m.se;
	}

	// cout<<"............priv......................"<<endl;
	int num_man;
	cin>>num_man;

	rep(i,0,num_man){
		string man;
		int cnt;
		cin>>man>>cnt;
		string pp;
		rep(i,0,cnt){
			cin>>pp;
			auto pp_det = split(pp);

			// 一个角色拥有的权限,对于某项也取最高,貌似没必要
			all[make_pair(man, pp_det.fi)] = max(all[make_pair(man, pp_det.fi)], pp_det.se);
		}
	}

	// cout<<"............personal priv......................"<<endl;

	cin>>num_man;
	rep(i,0,num_man){
		string man;
		int cnt;
		cin>>man>>cnt;
		string pp;
		rep(i,0,cnt){
			cin>>pp;
			for(auto e:p_info){
				//如果多个角色有这个权限,取最高的
				ans[make_pair(man, e.fi)]=max(ans[make_pair(man, e.fi)],all[make_pair(pp,e.fi)]);
			}
		}
	}

	// cout<<"............Query begin......................"<<endl;

	int query;
	cin>>query;
	string name,quer;
	while(query--){
		cin>>name>>quer;
		solve(name, quer);
	}
	return 0;
}
posted @ 2020-09-10 13:14  CrosseaLL  阅读(96)  评论(0编辑  收藏  举报