第三届“传智杯”全国大学生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;
}
posted @ 2020-12-20 21:51  洛绫璃  阅读(401)  评论(0编辑  收藏  举报