20230831 巨人网络 笔试 AK
AK了,九点半再发。。。
T1 魔鬼C++字符串处理 + 拓扑排序
#include <bits/stdc++.h> using namespace std; using pii = pair<int, int> ; pii getab(string &s) { int left = 0, right = 0; pii ans; int n = s.size(); int i = 0; for(; i < n; ++i) { if(s[i] == ',') { ans.first = left; break; } else { left = left * 10 + s[i] - '0'; } } i += 2; for(; i < n; ++i) { if(s[i] == '}') { ans.second = right; break; } else { right = right * 10 + s[i] - '0'; } } return ans; } int main() { string s; getline(cin, s); s = s.substr(1, s.size() - 2); stringstream ss(s); vector<pii> ve; map<int, int> in_deg; map<int, vector<int>> g; string str; while(getline(ss, str, '{')) { if(!str.empty()) { pii tp = getab(str); int a = tp.first; int b = tp.second; ++in_deg[b]; if(in_deg.find(a) == in_deg.end()) { in_deg[a] = 0; } ve.push_back(make_pair(a, b)); g[a].push_back(b); } } queue<int> q; for(auto &&[x,y]: in_deg) { if(y == 0) { q.push(x); } } while (!q.empty()) { int x = q.front(); q.pop(); for(int y: g[x]) { if(--in_deg[y] == 0) { q.push(y); } } } int flag = true; for(auto &&[x, y]: in_deg) { if(y) { flag = false; break; } } if(flag) { cout << "Yes\n"; } else { cout << "No\n"; } return 0; }
T2 线段树 + map
注意几个点:
- 线段树区间操作需要左闭右开,因为观察样例可以发现:1->3买了票 且 4->5买了票,实际上这个时候是可以买3->4的票的
- 观察样例,退(a, b)的票时候只能退恰好购买的是(a, b)这个pair的票,否则就退票失败
不过还是想骂,题意说得不太清楚,完全只能看样例猜题意。
#include <bits/stdc++.h> using namespace std; using ll = long long; using pii = pair<int, int>; struct SegTree { struct Node { ll maxh, tg; Node(): maxh(0), tg(0) {} }; #define ls (i<<1) #define rs (i<<1|1) vector<Node> tr; SegTree() = default; SegTree(const int &N): tr((N + 1) << 2) {} void push_down(int i, int l, int r) { if(!tr[i].tg) return; ll k = tr[i].tg; tr[ls].maxh += k; tr[rs].maxh += k; tr[ls].tg += k; tr[rs].tg += k; tr[i].tg = 0; } void push_up(int i) { tr[i].maxh = max(tr[ls].maxh, tr[rs].maxh); } void add_range(int i, int l, int r, int L, int R, int k) { if (l >= L && r <= R) { tr[i].tg += k; tr[i].maxh += k; return; } push_down(i, l, r); int mid = (l + r) >> 1; if(mid >= L) add_range(ls, l, mid, L, R, k); if(mid + 1 <= R) add_range(rs, mid + 1, r, L, R, k); push_up(i); } ll getmax(int i, int l, int r, int L, int R) { if (l >= L && r <= R) { return tr[i].maxh; } push_down(i, l, r); int mid = (l + r) >> 1; ll ret = LLONG_MIN; if(mid >= L) ret = max(ret, getmax(ls, l, mid, L, R)); if(mid + 1 <= R) ret = max(ret, getmax(rs, mid + 1, r, L, R)); return ret; } }; void solve() { int n, m, q; cin >> n >> m >> q; SegTree tr(n); map<pii, ll> ma; int a, b, c; char ch; for(int i = 0; i < q; ++i) { cin >> ch; cin >> a >> b; a++; if(ch == 'Q') { cout << m - tr.getmax(1, 1, n, a, b) << '\n'; } else if(ch == 'B') { cin >> c; ll rem = m - tr.getmax(1, 1, n, a, b); if(rem >= c) { cout << "OK!\n"; tr.add_range(1, 1, n, a, b, c); ma[make_pair(a, b)] += c; } else { cout << "Fail!\n"; } } else if(ch == 'R') { cin >> c; if(ma.find(make_pair(a, b)) != ma.end() && ma[make_pair(a, b)] >= c) { cout << "OK!\n"; tr.add_range(1, 1, n, a, b, -c); ma[make_pair(a, b)] -= c; } else { cout << "Fail!\n"; } } } } int main() { cin.tie(nullptr)->sync_with_stdio(false); solve(); return 0; }#巨人网络校招##笔试#