第十三届蓝桥杯大赛软件赛决赛_CB个人题解

赛后复盘:

最终国二…感觉写错这么多还能国二…可见CB的氵…

A没写出来…

E最短路板子题不知道为啥wa…

F写了个暴搜…

G不会写…

H预处理log没处理到log [n]以及x==y时输出了1…直接0分

J读错题写了个假dp

感觉赛中脑子被埋了,正常发挥应该有国一的,下次再战吧…

然后该准备暑假集训了2333

试题A: 2022

tag: dp

379187662194355221

#include<bits/stdc++.h>
using namespace std;
using LL = long long;

LL dp[2050][20];
signed main() {
    cin.tie(nullptr)->sync_with_stdio(false);

    dp[0][0] = 1;
    for (int i = 1; i <= 2022; ++ i) {
        for (int j = 1; j <= min(10, i); ++ j) {
            dp[i][j] = dp[i - j][j] + dp[i - j][j - 1];
        }
    }
    cout << dp[2022][10] << '\n';
    return 0;
}

试题B: 钟表

tag: 枚举、暴力

4:48:00(好像写的这个)

试题C: 卡牌

tag: 二分

#include<bits/stdc++.h>
using namespace std;
using LL = long long;
const int N = 2e5 + 5, MOD = 998244353, INF = 0x3f3f3f3f;

int n; LL m;
pair< int, int > a[N];
bool check(LL mid) {
    LL cnt = 0;
    for (int i = 1; i <= n; ++ i) {
        if (a[i].first < mid) 
            cnt += mid - a[i].first;
    }
    return cnt <= m;
}
signed main() {
    cin.tie(nullptr)->sync_with_stdio(false);

    cin >> n >> m;
    for (int i = 1; i <= n; ++ i)
        cin >> a[i].first;
    for (int i = 1; i <= n; ++ i) 
        cin >> a[i].second;
    sort(a + 1, a + n + 1, [&](const pair< int, int > &x, const pair< int, int > &y) {
        return x.first + x.second < y.first + y.second;
    });
    int l = 0, r = a[1].first + a[1].second, ans = 0;
    while (l <= r) {
        int mid = (l + r) >> 1;
        if (check(mid)) {
            l = mid + 1, ans = mid;
        } else {
            r = mid - 1;
        }
    }
    cout << ans << '\n';
    return 0;
}

试题D: 最大数字

tag: 贪心、枚举

#include<bits/stdc++.h>
using namespace std;
using LL = long long;

signed main() {
    cin.tie(nullptr)->sync_with_stdio(false);

    string s;
    int A, B;
    cin >> s >> A >> B;
    vector < int > vec;
    for (auto &ch : s) 
        vec.push_back(ch - '0');
    int n = vec.size();
    LL ans = 0;
    for (int S = 0; S < (1 << n); ++ S) {
        int init_A = A, init_B = B;
        LL res = 0;
        vector< int > vecc = vec;
        for (int i = 0; i < n; ++ i) {
            if (S >> i & 1) {
                if (init_A >= 9 - vec[i]) {
                    init_A -= 9 - vec[i];
                    vecc[i] = 9;
                } else {
                    vecc[i] = vec[i] + init_A;
                    init_A = 0;
                }
            } else {
                if (init_B >= vec[i] + 1) {
                    init_B -= vec[i] + 1;
                    vecc[i] = 9;
                } else {
                    continue;
                }
            }
            res = res * 10 + vecc[i];
        }
        ans = max(ans, res);
    }
    cout << ans << '\n';
    return 0;
}

试题E: 出差

tag: 最短路

#include<bits/stdc++.h>
using namespace std;
using LL = long long;
const int N = 1005;

int n, m, c[N];
vector< pair< int, int > > adj[N];
struct node {
    int to, cost;
    bool operator < (const node &o) const {
        return cost > o.cost;
    }
};
int dis[N];
bool vis[N];
int dijkstra() {
    memset(dis, 0x3f, sizeof dis);
    priority_queue< node > q;
    q.push({1, dis[1] = 0});
    while (!q.empty()) {
        node p = q.top(); q.pop();
        if (vis[p.to]) continue;
        vis[p.to] = true;
        for (auto &[y, z] : adj[p.to]) {
            if (!vis[y] && dis[y] > dis[p.to] + z) {
                q.push({y, dis[y] = dis[p.to] + z});
            }
        }
    }
    return dis[n];
}
signed main() {
    cin.tie(nullptr)->sync_with_stdio(false);

    cin >> n >> m;
    for (int i = 1; i <= n; ++ i)
        cin >> c[i];
    c[n] = 0;
    while (m -- ) {
        int u, v, w;
        cin >> u >> v >> w;
        adj[u].push_back({v, c[v] + w});
        adj[v].push_back({u, c[u] + w});
    }
    cout << dijkstra() << '\n';
    return 0;
}

试题F: 费用报销

tag: dp

#include<bits/stdc++.h>
using namespace std;
using LL = long long;
const int N = 1005, M = 5005;

int n, m, k;
int month[] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
pair< int, int > a[N];
bitset< M > dp[N];
bool vis[M];
signed main() {
    cin.tie(nullptr)->sync_with_stdio(false);

    cin >> n >> m >> k;
    for (int i = 1; i <= n; ++ i) {
        int x, y, z;
        cin >> x >> y >> z;
        for (int j = 1; j < x; ++ j) y += month[j];
        a[i] = {y, z};
    }
    sort(a + 1, a + n + 1);
    for (int i = 1; i <= n; ++ i) {
        dp[i][a[i].second] = true;
        for (int j = 1; j < i && a[j].first <= a[i].first - k; ++ j) {
            dp[i] |= dp[j] << a[i].second;
        }
    }
    for (int i = 1; i <= n; ++ i) {
        for (int j = 1; j <= m; ++ j) {
            vis[j] |= dp[i][j];
        }
    }
    for (int i = m; i; -- i) {
        if (vis[i]) {
            cout << i << '\n';
            return 0;
        }
    }
    return 0;
}

试题G: 故障

tag: 数学、模拟

先放一个错误代码,不想写模拟qwq

#include<bits/stdc++.h>
using namespace std;
using LL = long long;
const int N = 25;

int n, m, k;
double P[N], p[N][N], ans[N];
bool vis[N];
vector< int > vec[N];
signed main() {
    cin.tie(nullptr)->sync_with_stdio(false);

    cin >> n >> m;
    for (int i = 1; i <= n; ++ i) {
        cin >> P[i];
        P[i] /= 100.0;
    }
    for (int i = 1; i <= n; ++ i) {
        for (int j = 1; j <= m; ++ j) {
            cin >> p[i][j];
            if (p[i][j] != 0) {
                vec[j].push_back(i);
            }
            p[i][j] /= 100.0;
        }
    }
    cin >> k;
    for (int i = 1, x; i <= k; ++ i) {
        cin >> x;
        vis[x] = true;
    }
    for (int j = 1; j <= m; ++ j) {
        vector< double > now_p(n + 1);
        double all_p = 0.0;
        if (vis[j]) {
            for (auto &x : vec[j]) {
                all_p += P[x];
                double pp = 1.0;
                for (int i = 1; i <= m; ++ i) {
                    if (i == j) pp *= p[x][i];
                    else pp *= (1.0 - p[x][i]);
                }
                now_p[x] = pp;
            }
            for (auto &x : vec[j]) {
                now_p[x] *= P[x] / all_p;
            }
            double all_pp = accumulate(now_p.begin() + 1, now_p.begin() + n + 1, 0.0);
            for (auto &x : vec[j]) {
                ans[x] += now_p[x] / all_pp;
            }
        }
    }
    double all_p = accumulate(ans + 1, ans + n + 1, 0.0);
    vector< pair< double, int > > res;
    for (int i = 1; i <= n; ++ i) {
        res.push_back({ans[i] / all_p, i});
    }
    sort(res.begin(), res.end(), greater< pair< double, int > >());
    for (auto &[x, y] : res) {
        cout << y << ' ' << fixed << setprecision(2) << x * 100.0 << '\n';
    }
    return 0;
}

试题H: 机房

tag: LCA

#include<bits/stdc++.h>
using namespace std;
using LL = long long;
const int N = 2e5 + 5, MOD = 998244353, INF = 0x3f3f3f3f;

int n, m;
vector< int > adj[N];
int dep[N], f[N][20], lg[N], dis[N];
void dfs(int x, int p) {
    dis[x] += dis[p];
    for (int i = 1; i <= lg[n]; ++ i)  f[x][i] = f[f[x][i - 1]][i - 1];
    for (auto &y : adj[x]) {
        if (y == p) continue;
        f[y][0] = x;
        dep[y] = dep[x] + 1;
        dfs(y, x);
    }
}
int lca(int x, int y) {
    if (dep[x] > dep[y]) swap(x, y);
    for (int i = lg[n]; i >= 0; -- i) {
        if (dep[f[y][i]] >= dep[x]) y = f[y][i];
    }
    if (x == y) return x;
    for (int i = lg[n]; i >= 0; -- i) {
        if (f[x][i] != f[y][i]) {
            x = f[x][i], y = f[y][i];
        }
    }
    return f[x][0];
}
signed main() {
    cin.tie(nullptr)->sync_with_stdio(false);

    cin >> n >> m;
    for (int i = 1; i < n; ++ i) {
        int u, v;
        cin >> u >> v;
        adj[u].push_back(v);
        adj[v].push_back(u);
        ++ dis[u];
        ++ dis[v];
    }
    for (int i = 2; i <= n; ++ i) lg[i] = lg[i >> 1] + 1;
    dep[1] = 1;
    dfs(1, 0);
    while (m -- ) {
        int x, y;
        cin >> x >> y;
        cout << dis[x] + dis[y] - dis[lca(x, y)] - dis[f[lca(x, y)][0]] << '\n';
    }
    return 0;
}

试题I: 齿轮

tag: 枚举、暴力

#include<bits/stdc++.h>
using namespace std;
using LL = long long;
const int N = 2e5 + 5, MOD = 998244353, INF = 0x3f3f3f3f;

int n, q, a[N], cnt[N];
bool ans[N];
signed main() {
    cin.tie(nullptr)->sync_with_stdio(false);

    cin >> n >> q;
    for (int i = 1; i <= n; ++ i) {
        cin >> a[i];
        ++ cnt[a[i]];
    }
    for (int i = 1; i <= 200000; ++ i) {
        if (cnt[i] >= 2)
            ans[1] = true;
        for (int j = i * 2; j <= 200000; j += i) {
            if (cnt[j] && cnt[i])
                ans[j / i] = true;
        }
    }
    while (q -- ) {
        int x;
        cin >> x;
        cout << (ans[x] ? "YES" : "NO") << '\n';
    }
    return 0;
}

试题J: 搬砖

tag: dp

#include<bits/stdc++.h>
using namespace std;
using LL = long long;

int n, dp[400005];
pair< int, int > a[1005];
signed main() {
    cin.tie(nullptr)->sync_with_stdio(false);

    cin >> n;
    for (int i = 1; i <= n; ++ i) {
        cin >> a[i].first >> a[i].second;
    }
    sort(a + 1, a + n + 1, [&](pair< int, int > &x, pair< int, int > &y) {
        return x.first + x.second < y.first + y.second;
    });
    for (int i = 1; i <= n; ++ i) {
        for (int j = a[i].second; j >= 0; -- j) {
            dp[j + a[i].first] = max(dp[j + a[i].first], dp[j] + a[i].second);
        }
    }
    cout << *max_element(dp, dp + 400001) << '\n';
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值