CSP 202206-3 角色授权

链接

大模拟,用了 map,但是 TLE 了;好在有部分分,能得80.

代码如下
#include<bits/stdc++.h>
using namespace std;
int const N=5005, M=505;
int n,m,q,ID[M];	// ID[关联编号] = 角色编号 
string curname, curop, curkd, curnm; // 当前操作的 用户,操作,资源种类,资源名称 
map<string, int> chaname2chaid;
//vector<int> cocha; // 当前操作关联的角色 
map<string, int> curgroups; // 当前操作涉及到的用户组 
//角色 
struct Chara{
	string name;
	map<string, int> op, kd, nm; //操作,资源种类,资源名称
}cha[M];
//关联
struct Connection{
	string cname;
	map<string, int> users;
	vector<string> ugroups;
//	vector<pair<int, string> > object; // pair<类型,名称>,类型 0 表示用户,类型 1 表示用户组 
}con[M]; 
bool can(int id) // 第 id 个角色是否能执行操作 
{
	string star = "*";
	if((cha[id].op.find(curop) == cha[id].op.end()) && (cha[id].op.find(star) == cha[id].op.end()))
		return 0;
	else if((cha[id].kd.find(curkd) == cha[id].kd.end()) && (cha[id].kd.find(star) == cha[id].kd.end()))
		return 0;
	else if((cha[id].nm.find(curnm) == cha[id].nm.end()) && (cha[id].nm.size() > 0))
		return 0;
	else return 1;
}
bool findcha()
{
	for(int i=1;i<=m;i++)	// 遍历每个关联 
	{
		if(con[i].users.find(curname) != con[i].users.end())	// user
		{
			if(ID[i]>-1)
			{
				if(can(ID[i])) return 1;
			}
			continue;
		}
		//遍历这个关联的每个用户组
		for(vector<string>::iterator it = con[i].ugroups.begin(); it!=con[i].ugroups.end(); it++)
		{
			if(curgroups.find((*it)) != curgroups.end())	// ugroup
			{
				if(ID[i]>-1)
				{
					if(can(ID[i])) return 1;
				}
				break;
			}
		}
	}
	return 0;
}
int main()
{
	ios::sync_with_stdio(0);
	cin.tie(0); cout.tie(0);
	cin>>n>>m>>q;
	string tmp;
	// 角色 
	for(int i=1,nv,no,nn;i<=n;i++)
	{
		cin>>cha[i].name>>nv;
		chaname2chaid[cha[i].name] = i;
		for(int j=1;j<=nv;j++)
		{
			cin>>tmp;
			cha[i].op[tmp]=1;
		}
		cin>>no;
		for(int j=1;j<=no;j++)
		{
			cin>>tmp;
			cha[i].kd[tmp]=1;
		}
		cin>>nn;
		for(int j=1;j<=nn;j++)
		{
			cin>>tmp;
			cha[i].nm[tmp]=1;
		}
	}
	string type;
	//关联 
	for(int i=1,ns;i<=m;i++)
	{
		cin>>con[i].cname>>ns;	// cname 是角色名称
		
		if(chaname2chaid.find(con[i].cname) != chaname2chaid.end())
			ID[i] = chaname2chaid[con[i].cname];
		else ID[i] = -1; // 不存在这个角色 
		 
		for(int j=1;j<=ns;j++)
		{
			cin>>type>>tmp;
			if(type[0]=='u') con[i].users[tmp] = 1; // user
			else con[i].ugroups.push_back(tmp); // ugroup
		}
	}
	for(int i=1,ng;i<=q;i++)
	{
		cin>>curname>>ng;
		curgroups.clear();
		for(int j=1;j<=ng;j++)
		{
			cin>>tmp;
			curgroups[tmp]=1;
		}
		cin>>curop>>curkd>>curnm;
		cout<<findcha()<<endl;
	}
	return 0;
}

网上有100分的代码,看来是用 map 直接存用户(组)名到其关联的角色(set), 然后各种 count() 就很快。

posted @ 2023-05-28 10:55  Zinn  阅读(66)  评论(0编辑  收藏  举报