使用C++的CCF-CSP满分解决方案 202206-3 角色授权

题目过长,就不贴了……

解题思路

反复阅读题目,会发现其实用户和用户组是一回事,二者是并列的关系,而不是包含的关系,所以没必要把二者区分。
每个角色用名称标识,再加上三个集合存储信息,然后就没什么难的了。

注意事项

在写的时候遇到了如下问题:

  • 运行时间过长
    在这里插入图片描述

解决方法是加上一句话就好:

//提高cin,cout的速度 
ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);

  • 注意理解题意
    我最开始以为是所有的权限共享,后来写错之后发现,原来是只能用一个角色来过三个关卡的。

满分代码实现:

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

/*
class Client {
public:
	string name;
	string kind;
	
	Client(const string& name, const string& kind) : name(name), kind(kind) {}
}; 
*/

class Role {
public:
	string name;
	set<string> operation;
	set<string> sourceKind;
	set<string> sourceName;
	
	Role(string name, set<string> operation, set<string> sourceKind,
	set<string> sourceName) : name(name), operation(operation), sourceKind(sourceKind),
	sourceName(sourceName) {}
	
    bool operator<(const Role &other) const {
        return name <= other.name;
	}	
};

/*
class Connect {
public:
	map<string, Role> _map;
};
*/

class Solve {
private:
	unordered_map<string, Role> roles;
	unordered_map<string, vector<string> > connect;
	void getRole(int n);
	void getConnect(int m);
	void judgePrint();
	bool judge(const vector<string>& names);
public:
	void solve();
};

inline void Solve::getRole(int n) {
	string name;
	set<string> operation;
	set<string> sourceKind;
	set<string> sourceName;
	string tmp;
	int a = 0;
	for (int i = 0; i < n; i++) {
		operation.clear();
		sourceKind.clear();
		sourceName.clear();
		cin >> name;
		cin >> a;
		for (int j = 0; j < a; j++) {
			cin >> tmp;
			operation.insert(tmp);
		}
		cin >> a;
		for (int j = 0; j < a; j++) {
			cin >> tmp;
			sourceKind.insert(tmp);
		}
		cin >> a;
		for (int j = 0; j < a; j++) {
			cin >> tmp;
			sourceName.insert(tmp);
		}
		roles.insert(make_pair(name, Role(name, operation, sourceKind, sourceName)));
	}
}

inline void Solve::getConnect(int m) {
	int num = 0;
	string roleName;
	string clientName;
	for (int i = 0; i < m; i++) {
		cin >> roleName;
		cin >> num;
		for (int j = 0; j < num; j++) {
			cin >> clientName;
			cin >> clientName;
			connect[clientName].push_back(roleName);
		}
	}
}

inline void Solve::solve() {
	int n = 0, m = 0, q = 0;
	cin >> n >> m >> q;
	getRole(n); 
	getConnect(m);
	for (int i = 0; i < q; i++) {
		judgePrint();
	}	
}

inline void Solve::judgePrint() {
	string name;
	vector<string> names;
	cin >> name;
	names.push_back(name);
	int num = 0;
	cin >> num;
	for (int i = 0; i < num; i++) {
		cin >> name;
		names.push_back(name);
	}
	if (judge(names)) {
		cout << 1 << endl;
	}
	else {
		cout << 0 << endl;
	}
}
inline bool Solve::judge(const vector<string>& names) {
	string name, oper, kind, sname;
	cin >> oper >> kind >> sname;
	for (string name : names) {
		if (!connect.count(name)) continue;
		const vector<string>& vec = connect[name];
		for (string roleName : vec) {
			const Role& r = roles.at(roleName);
			if (r.operation.count("*") || r.operation.count(oper)) {
				if (r.sourceKind.count("*") || r.sourceKind.count(kind)) {
					if (r.sourceName.empty() || r.sourceName.count(sname)) {
						return true;
					}
				}
			}
		}
	}
	return false;
}

int main() {
	//提高cin,cout的速度 
	ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
	Solve solution;
	solution.solve();
	return 0;
}
  • 3
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值