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;
}