CSP认证题目合集

202209-3防疫大数据

时间:156ms

#include <bits/stdc++.h>
using namespace std;
/*
real_day
received_day
dangerous region check: receive a massage then [d0, d0 + 7) become dangerous
then if a user is in dangerous region and received_day < d0 + 7 --> dangerous user
but if received_day >= d0 + 7 and the region is safe, the user still keep safe
用户是否被列入危险,只看收到消息的当日该地区的状态,只有当日地区状态是危险,才看用户之前是否去过,判断是否是危险的

维护地区状态
判断用户在这一天是否被列入名单
*/
#define PII pair<int, int>
const int N = 1005;
int n;
int r;//危险地区数量
int m;//漫游数据数量
int region[N];
unordered_map<int, PII> state;//地区状态
unordered_map<int, int> len;//状态持续长度
set<array<int, 4>> users;//漫游信息
int ans[N], idx;//答案
void modify_region() {
	for (int i = 0;i < r;i ++) {
		state[region[i]] = {true, 7};
	}
	for (auto it = state.begin();it != state.end();) {
		int p = it->first;
		int st = it->second.first, live = it->second.second;
		live --;
		if (live < 0) {
			it = state.erase(it);
			len[p] = 0;
		} else {
			state[p] = {true, live};
			len[p] ++;
			it ++;
		}
	}
}
bool check(int now, int received_day, int d, int u, int w) {
	if (now - received_day >= 7) return false;
	if (now - d >= 7) return false;
	if (state.count(w) and state[w].first) {
		int l = len[w];
		if (now - l + 1 <= d and d <= now) return true;
		return false;
	} else return false;
}
void solve() {
	cin >> n;
	for (int i = 0;i < n;i ++) {
		cin >> r >> m;
		for (int j = 0;j < r;j ++) {
			cin >> region[j];
		}
		modify_region();
		for (int j = 0;j < m;j ++) {
			int d, u, w; cin >> d >> u >> w;
			users.insert({u, d, w, i});
		}
		idx = 0;
		for (auto it = users.begin();it != users.end();) {
			int u = it->at(0), d = it->at(1), w = it->at(2), rd = it->at(3);
			if (check(i, rd, d, u, w)) {
				if (idx == 0 or ans[idx - 1] != u) ans[idx ++] = u;
				it ++;
			} else {
				it = users.erase(it);
			}
		}
		
		cout << i << ' ';
		for (int i = 0;i < idx;i ++) cout << ans[i] << ' ';
		cout << '\n';
	}	
}
int main() {
	ios::sync_with_stdio(false);
	cin.tie(0);

	solve();
	return 0;
}

202206-3 角色授权

时间:1.421s

#include <bits/stdc++.h>
using namespace std;
/*
user <name, group>
src <kind, name>
action <user, op, src>

character <user(name), ops, srcs>

check character grant:
if this op not in character's ops and '*' not in ops: cant do
if this src.kind not in character's srcs.kinds and '*' not in srcs.kind: cant do
if this src.name not in character's srcs.name and src.name not NULL: cant do
else: do

link: <character.name, [username | usergroup]>

check user grant:
if username or usergroup in all characters' link: select this character
then
check all selected character grant
if all cant do: cantdo
else admit

该用户允许进行的操作是这些角色被允许进行的操作集合的并集。
*/
#define uset unordered_set
#define umap unordered_map
const int N = 505;
int n;//角色数量
int m;//角色关联数量
int q;//待检查操作数

struct Character {
	string name;
	uset<string> op, src_kind, src_name;
};

umap<string, int> mp;
vector<Character> ch;
umap<string, uset<int>> grmp, unmp;

bool check(string &chname, string &op_name, string &src_kind, string &src_name) {
// check character grant:
// if this op not in character's ops and '*' not in ops: cant do
// if this src.kind not in character's srcs.kinds and '*' not in srcs.kind: cant do
// if this src.name not in character's srcs.name and src.name not NULL: cant do
    int id = mp[chname];
    auto &t = ch[id];
    if (t.op.count(op_name) == 0 and t.op.count("*") == 0) return false;
    if (t.src_kind.count(src_kind) == 0 and t.src_kind.count("*") == 0) return false;
    if (t.src_name.count(src_name) == 0 and t.src_name.size() > 0) return false;
    return true;
}
void solve() {
	cin >> n >> m >> q;
	ch.resize(n);
	for (int i = 0;i < n;i ++) {
		cin >> ch[i].name;
		mp[ch[i].name] = i;
		auto &t = ch[i];

		int nv; cin >> nv;
		for (int j = 0;j < nv;j ++) {
			// read op
			string p; cin >> p;
			t.op.insert(p);
		}
		int no; cin >> no;
		for (int j = 0;j < no;j ++) {
			// read src kind
			string p; cin >> p;
			t.src_kind.insert(p);
		}
		int nn; cin >> nn;
		for (int j = 0;j < nn;j ++) {
			// read src name
			string p; cin >> p;
			t.src_name.insert(p);
		}
	}
    for (int i = 0;i < m;i ++) {
        string s; cin >> s;
        int ns; cin >> ns;
        for (int j = 0;j < ns;j ++) {
            char kind; cin >> kind;
            string name; cin >> name;
            if (kind == 'u') {
                unmp[name].insert(mp[s]);
            } else {
                grmp[name].insert(mp[s]);
            }
        }
    }

	for (int i = 0;i < q;i ++) {
		string un; cin >> un;
		int ng; cin >> ng;
		vector<string> groups(ng);
        bool flg = false;
        for (auto &gp : groups) {
			cin >> gp;
		}
		string op_name, src_kind, src_name;
		cin >> op_name >> src_kind >> src_name;
		
        for (auto &id : unmp[un]) {
            flg = check(ch[id].name, op_name, src_kind,src_name);
            if (flg) break;
        }
        if (!flg) {
            for (auto &gp : groups) {
                auto &ss = grmp[gp];
                for (auto &id : ss) {
                    flg = check(ch[id].name, op_name, src_kind,src_name);
                    if (flg) break;
                }
                if (flg) break;
            }
        }
        if (flg) cout << "1\n";
        else cout << "0\n";
	}
}
int main() {
	ios::sync_with_stdio(false);
	cin.tie(0);
	solve();
	return 0;
}

202109-2 非零段划分

#include <bits/stdc++.h>
using namespace std;

void solve() {
	int n; cin >> n;
	map<int, vector<int>> mp;
	for (int i = 0;i < n;i ++) {
		int t; cin >> t;
		mp[t].emplace_back(i);
	}
	
	int mx = 0, cnt = 0;
	vector<int> a(n);
	for (auto it = mp.rbegin();it != mp.rend();it ++) {
		int val = it->first;
		auto &pos = it->second;
		if (val == 0) continue;
		for (auto p : pos) {
			int ct = 0;
			if (p == 0 or a[p - 1] == 0) ct ++;
			if (p == n - 1 or a[p + 1] == 0) ct ++;
			if (ct == 2) cnt ++;
			else if (ct == 0) cnt --;
			a[p] = val;
		}
		mx = max(mx, cnt);
	}
	cout << mx;
}
int main() {
	ios::sync_with_stdio(false);
	cin.tie(0);
	solve();
	return 0;
}
posted @ 2023-03-13 19:11  Mxrurush  阅读(83)  评论(0编辑  收藏  举报