赞
踩
参考了
①CCF-CSP认证 202303 500分题解;
②bitset的基本用法
③表达式求值
自认代码结构相对清晰,给卡在这题的同学参考。
#include <bits/stdc++.h> using namespace std; const int N = 2510; typedef bitset<N> STATE; typedef pair<int, int> PII; int n, m; vector<PII> p; map<PII, STATE> d; map<int, STATE> S; stack<STATE> num; stack<char> op; void eval(){ STATE b = num.top(); num.pop(); STATE a = num.top(); num.pop(); char c = op.top(); op.pop(); STATE res; if (c == '&') res = a & b; else res = a | b; num.push(res); } STATE solve(string str){ stack<STATE>().swap(num), stack<char>().swap(op); for (int i = 0; i < str.size(); i ++ ){ char c = str[i]; if (isdigit(c)){ int x = 0, j = i; while (j < str.size() && isdigit(str[j])) x = x * 10 + str[j] - '0', j ++ ; char oper = str[j]; j ++ ; int y = 0; while (j < str.size() && isdigit(str[j])) y = y * 10 + str[j] - '0', j ++ ; i = j - 1; if (oper == ':') num.push(d[{x, y}]); else num.push(~d[{x, y}] & S[x]); } else if (c == '(') op.push(c); else if (c == ')'){ while (op.top() != '(') eval(); op.pop(); } else{ while (op.size() && op.top() != '(') eval(); op.push(c); } } while (op.size()) eval(); return num.top(); } int main(){ ios::sync_with_stdio(false); cin.tie(0); cin >> n; for (int i = 0; i < n; i ++ ){ int t; cin >> t; p.push_back({t, i}); int cnt; cin >> cnt; while (cnt -- ){ int x, y; cin >> x >> y; d[{x, y}][i] = 1; S[x][i] = 1; } } sort(p.begin(), p.end()); cin >> m; while (m -- ){ string str; cin >> str; STATE state = solve(str); vector<int> res; for (int i = 0; i < n; i ++ ){ int x = p[i].first, y = p[i].second; if (state[y]) res.push_back(x); } for (int i = 0; i < res.size(); i ++ ) cout << res[i] << " \n"[i == res.size() - 1]; if (res.empty()) cout << endl; } return 0; } /* 2 1 2 1 2 2 3 2 2 2 3 3 1 4 1:2 3~1 &(1:2)(2:3) |(1:2)(3:1) */
运行时间也还行
另外,有个很凑巧的递归写法,考场上试出来的。利用了scanf的机制,用%d读字符,会将读取的字符自动退回输入缓冲区,原用于接收的int变量tmp值未改变。
参考C语言使用%d读入字符会发生什么
#include <bits/stdc++.h> using namespace std; const int N = 2510; typedef bitset<N> STATE; typedef pair<int, int> PII; int n, m; vector<PII> p; map<PII, STATE> d; map<int, STATE> S; STATE get(){ int tmp = 0; scanf("%d", &tmp); if (tmp){ int x = tmp, y; char op; cin >> op >> y; if (op == ':') return d[{x, y}]; else return ~d[{x, y}] & S[x]; } char op; scanf("%c", &op); getchar(); STATE x = get(); getchar(); getchar(); STATE y = get(); getchar(); if (op == '&') return x & y; else return x | y; } int main(){ scanf("%d", &n); for (int i = 0; i < n; i ++ ){ int t; scanf("%d", &t); p.push_back({t, i}); int cnt; scanf("%d", &cnt); while (cnt -- ){ int x, y; scanf("%d %d", &x, &y); d[{x, y}][i] = 1; S[x][i] = 1; } } sort(p.begin(), p.end()); scanf("%d", &m); while (m -- ){ STATE state = get(); getchar(); vector<int> res; for (int i = 0; i < n; i ++ ){ int x = p[i].first, y = p[i].second; if (state[y]) res.push_back(x); } for (int i = 0; i < res.size(); i ++ ) printf(" %d" + !i, res[i]); puts(""); } return 0; } /* 2 1 2 1 2 2 3 2 2 2 3 3 1 4 1:2 3~1 &(1:2)(2:3) |(1:2)(3:1) */
时间慢了1s
更正常一点的写法
#include <bits/stdc++.h> using namespace std; const int N = 2510; typedef bitset<N> STATE; typedef pair<int, int> PII; int n, m; vector<PII> p; map<PII, STATE> d; map<int, STATE> S; string str; STATE state; int get(int u){ if (isdigit(str[u])){ int x = 0, y = 0; while (u < str.size() && isdigit(str[u])) x = x * 10 + str[u] - '0', u ++ ; char op = str[u]; u ++ ; while (u < str.size() && isdigit(str[u])) y = y * 10 + str[u] - '0', u ++ ; if (op == ':') state = d[{x, y}]; else state = ~d[{x, y}] & S[x]; return u; } char op = str[u]; u ++ ; u = get(u + 1); STATE x = state; u ++ ; u = get(u + 1); STATE y = state; if (op == '&') state = x & y; else state = x | y; return u + 1; } int main(){ scanf("%d", &n); for (int i = 0; i < n; i ++ ){ int t; scanf("%d", &t); p.push_back({t, i}); int cnt; scanf("%d", &cnt); while (cnt -- ){ int x, y; scanf("%d %d", &x, &y); d[{x, y}][i] = 1; S[x][i] = 1; } } sort(p.begin(), p.end()); scanf("%d", &m); while (m -- ){ cin >> str; get(0); vector<int> res; for (int i = 0; i < n; i ++ ){ int x = p[i].first, y = p[i].second; if (state[y]) res.push_back(x); } for (int i = 0; i < res.size(); i ++ ) printf(" %d" + !i, res[i]); puts(""); } return 0; } /* 2 1 2 1 2 2 3 2 2 2 3 3 1 4 1:2 3~1 &(1:2)(2:3) |(1:2)(3:1) */
可能更好想到的做法,属性值直接存储,每位单独进行判断。不用unorder_map则70分。
#include <bits/stdc++.h> using namespace std; const int N = 2510; typedef pair<int, int> PII; int n, m; vector<PII> p; unordered_map<int, int> v[N]; string str; bool flag; int aim; int get(int u){ if (isdigit(str[u])){ int x = 0, y = 0; while (u < str.size() && isdigit(str[u])) x = x * 10 + str[u] - '0', u ++ ; char op = str[u]; u ++ ; while (u < str.size() && isdigit(str[u])) y = y * 10 + str[u] - '0', u ++ ; if (!v[aim].count(x)) flag = false; else if (op == ':' && v[aim][x] == y) flag = true; else if (op == '~' && v[aim][x] != y) flag = true; else flag = false; return u; } char op = str[u]; u ++ ; u = get(u + 1); bool x = flag; u ++ ; u = get(u + 1); bool y = flag; if (op == '&') flag = x && y; else flag = x || y; return u + 1; } int main(){ scanf("%d", &n); for (int i = 0; i < n; i ++ ){ int t; scanf("%d", &t); p.push_back({t, i}); int cnt; scanf("%d", &cnt); while (cnt -- ){ int x, y; scanf("%d %d", &x, &y); v[i][x] = y; } } sort(p.begin(), p.end()); scanf("%d", &m); while (m -- ){ cin >> str; vector<int> res; for (int i = 0; i < n; i ++ ){ int x = p[i].first, y = p[i].second; aim = y; get(0); if (flag) res.push_back(x); } for (int i = 0; i < res.size(); i ++ ) printf(" %d" + !i, res[i]); puts(""); } return 0; } /* 2 1 2 1 2 2 3 2 2 2 3 3 1 4 1:2 3~1 &(1:2)(2:3) |(1:2)(3:1) */
时间慢了很多
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。