• 博客园logo
  • 会员
  • 周边
  • 新闻
  • 博问
  • 闪存
  • 赞助商
  • YouClaw
    • 搜索
      所有博客
    • 搜索
      当前博客
  • 写随笔 我的博客 短消息 简洁模式
    用户头像
    我的博客 我的园子 账号设置 会员中心 简洁模式 ... 退出登录
    注册 登录

RomanLin

  • 博客园
  • 联系
  • 订阅
  • 管理

公告

View Post

【第十七届蓝桥杯大赛】省赛 C/C++ B组 题解

A题 青春常数

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

int main() {
    cout << 2026202520242023LL / 2LL + 1LL;
    return 0;
}

B题 双碳战略


C题 循环右移

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

int T;
ll n, x, y;

int main() {
    ios::sync_with_stdio(false);cin.tie(nullptr);cout.tie(nullptr);
    cin >> T;
    while (T --) {
        cin >> n >> x >> y;
        cout << (x <= y ? y - x + 1LL : 0LL) << '\n';
    }
    return 0;
}

D题 蓝桥竞技

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

int main() {
    ios::sync_with_stdio(false);cin.tie(nullptr);cout.tie(nullptr);
    int T, n, x;
    cin >> T;
    while (T --) {
        cin >> n;
        int mx = 0;
        long long sum = 0LL;
        for (int i = 0; i < n; ++ i) {
            cin >> x;
            sum += x;
            mx = max(mx, x);
        }
        if (sum % 5 || sum / 5 < mx) cout << "F\n";
        else cout << "T\n";
    }
    return 0;
}

E题 LQ聚合

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

int main() {
    ios::sync_with_stdio(false);cin.tie(nullptr);cout.tie(nullptr);
    ll ans = 0LL, res = 0LL;
    int n;
    string s;
    cin >> n >> s;
    vector<int> pst(n + 1);
    for (int i = n - 1; i >= 0; -- i) {
        if (s[i] == 'Q' || s[i] == '?') pst[i] = pst[i + 1] + 1;
        else {
            pst[i] = pst[i + 1];
            res += pst[i];
        }
    }
    ans = res;// 这是全填 Q 的答案
//    cout << "-1 => " << ans << '\n';
    int cntL = 0;// 统计 L 的个数
    for (int i = 0; i < n; ++ i) {
        if (s[i] == 'L') ++ cntL;
        else if (s[i] == '?') {
            res -= cntL;// 原本填 Q,要扣掉
            res += pst[i] - 1;// 现在填 L,要加上
            ++ cntL;// L 的数量要加 1
        }
        ans = max(ans, res);
//        cout << i << " => " << ans << '\n';
    }
    cout << ans;
    return 0;
}

F题 应急布线

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

int main() {
    ios::sync_with_stdio(false);cin.tie(nullptr);cout.tie(nullptr);
    int n, m, u, v, num = 0;
    cin >> n >> m;
    vector<int> dsu(n + 1), cnt(n + 1);
    iota(dsu.begin(), dsu.end(), 0);
    auto find = [&](auto &&find, int x) -> int {
        return x == dsu[x] ? x : dsu[x] = find(find, dsu[x]);
    };
    auto merge = [&](int x, int y) -> void {
        dsu[find(find, x)] = find(find, y);
    };
    while (m --) {
        cin >> u >> v;
        merge(u, v);
    }
    for (int i = 1; i <= n; ++ i) {
        cnt[find(find, i)] ++;
    }
    for (int i = 1; i <= n; ++ i) {
        if (cnt[i] > 0) ++ num;
    }
    cout << num - 1 << ' ' << ((num - 1) * 2 + n - 1) / n << '\n';
    return 0;
}

G题 理性温度

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

constexpr int N = 2e5 + 7;
int n, m;
int a[N], b[N];

int main() {
    ios::sync_with_stdio(false);cin.tie(nullptr);cout.tie(nullptr);
    cin >> n;
    map<int, vector<int>> mp;
    int ans = 0, res = 0;
    for (int i = 1; i <= n; ++ i) cin >> a[i];
    for (int i = 1; i <= n; ++ i) {
        cin >> m;
        m -= a[i];
        if (m != 0) mp[m].emplace_back(i);
        b[i] = !m ? b[i - 1] + 1 : b[i - 1];
    }

    res = ans = b[n];

    // 分组循环
    // 组内双指针遍历
    // 核心思路:
    //      若不能将数组改为理想数值,等价于未改动。所以更改的k的左右边界,我只考虑同一组里面的。
    //      多改只可能答案≤左右边界在同一组里面的
    //      因为其他组的要么是满足,要么是不满足
    //      但其他组改为我当前组的k,必定还是不满足;但原来满足的可能就不满足了。所以答案只会更劣
    //      因此左右边界只枚举同一组
    for (auto &[k, v]: mp) {
        int sz = v.size(), i, j;
        for (i = 0, j = 0; i < sz; ++ i) {
            // 对 [v[i], v[j]] 上的每个数执行 += k 的操作
            int add = i - j + 1;// 能多这么多个
            int minus = b[v[i]] - b[v[j] - 1];// 会少这么多个
            if (j <= i && add <= minus) {// 亏了/没赚
                ++ j;
                -- i;
            } else {
                ans = max(ans, res - minus + add);
            }
        }
        for (i = sz - 1; j <= i; ++ j) {
            int add = i - j + 1;// 能多这么多个
            int minus = b[v[i]] - b[v[j] - 1];// 会少这么多个
            ans = max(ans, res - minus + add);
        }
    }

    cout << ans << '\n';
    return 0;
}

H题 足球训练


posted on 2026-04-14 23:15  RomanLin  阅读(6)  评论(0)    收藏  举报

刷新页面返回顶部
 
博客园  ©  2004-2026
浙公网安备 33010602011771号 浙ICP备2021040463号-3