第三屆“傳智杯”全國大學生IT技能大賽
阿新 • • 發佈:2020-12-20
第三屆“傳智杯”全國大學生IT技能大賽
T160507 A - 課程報名
提議模擬, 就不放程式碼了
B - 期末考試成績
模擬題意
T160509 C - 志願者
自己手寫個排序函式就行
T160510 D - 終端
寫個map存每個字串的時間, 輸出的時候先放到另一個容器裡排序輸出即可
T160513 E - 運氣
爆搜
T160511 F - 遊戲
\(O(n^2)\) 暴力找能和自己連邊的最小值的點, 正反來一次
就成了最小生成樹
vector<pair<int, PII>> e; int c1, c2, f[N]; int find(int x) { return f[x] == x ? x : f[x] = find(f[x]); } int main() { IOS; cin >> n >> c1 >> c2; rep (i, 1, n) cin >> f[i]; rep (i, 1, n) { int wx = 2e9, s = 0; rep (j, i + 1, n) { if (f[i] == f[j]) continue; int w = __builtin_popcount(f[i] ^ f[j]) == 1 ? c1 : c2; if (wx > w) wx = w, s = j; } if (wx != 2e9) e.pb({ wx, { i, s } }); } per (i, n, 1) { int wx = 2e9, s = 0; per (j, i - 1, 1) { if (f[i] == f[j]) continue; int w = __builtin_popcount(f[i] ^ f[j]) == 1 ? c1 : c2; if (wx > w) wx = w, s = j; } if (wx != 2e9)e.pb({ wx, { i, s } }); } rep (i, 1, n) f[i] = i; sort(all(e)); ll ans = 0; for (auto &i : e) { int x = find(i.se.fi), y = find(i.se.se); if (x == y) continue; ans += i.fi; f[x] = y; } cout << ans; return 0; }
T160512 G - 森林
還是並查集, 沒點創意
int fa[N], s[N], e[N][2], op[N][2], ans[N], cnt; bool pd[N]; stack<int> a[N]; int find(int x) { int i = x, j, r = x; while (fa[r] != r) r = fa[r]; while (fa[i] != r) j = fa[i], fa[i] = r, i = j; return r; } void unit(int x, int y) { x = find(x), y = find(y); if (x == y) return; fa[x] = y; s[y] += s[x]; } int main() { IOS; cin >> n >> m; rep (i, 1, n) { int t; cin >> t; a[i].push(t); fa[i] = i; } rep (i, 1, n - 1) cin >> e[i][0] >> e[i][1]; rep (i, 1, m) { cin >> op[i][0] >> op[i][1]; if (op[i][0] == 1) pd[op[i][1]]=1; else if (op[i][0] == 2) { cin >> t; a[op[i][1]].push(t); } } rep (i, 1, n) s[i] = a[i].top(); rep (i, 1, n - 1) if(!pd[i]) unit(e[i][0], e[i][1]); per (i, m, 1) { switch (op[i][0]) { case 1: unit(e[op[i][1]][0], e[op[i][1]][1]); break; case 2: s[find(op[i][1])]-=a[op[i][1]].top(); a[op[i][1]].pop(); s[find(op[i][1])]+=a[op[i][1]].top(); break; case 3: ans[++cnt]=s[find(op[i][1])]; break; } } per (i, cnt, 1) cout << ans[i] << '\n'; return 0; }