1. 程式人生 > 實用技巧 >第三屆“傳智杯”全國大學生IT技能大賽

第三屆“傳智杯”全國大學生IT技能大賽

第三屆“傳智杯”全國大學生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;
}