前言

好久不见,最近区域赛什么的有点忙,鸽了两周,不会G待补,看不懂我的文字题解的去牛客b站的官网看苯环哥哥的视频题解,讲得很好!


题解


A.小苯吃糖果

比较一下最大的数和其他两个数的和哪个大就好了

#include<bits/stdc++.h>

using i64 = long long;

void solve() {
    std::vector<int> a(3);
    int sum = 0;
    for (int i = 0; i < 3; i++) {
        std::cin >> a[i];
        sum += a[i];
    }   

    std::sort(a.begin(), a.end());
    std::cout << std::max(a[0] + a[1], a[2]);
}  

signed main() {
    std::ios::sync_with_stdio(0);
    std::cout.tie(0);   
    std::cin.tie(0);
    
    i64 t = 1; 
    // std::cin >> t;
    while (t--) {
        solve();
    }
}

B.小苯的排列构造

从大到小输出n到1即可, + 1 + n,比如长度为5时,a数组为

#include<bits/stdc++.h>

using i64 = long long;

void solve() {
    int n;
    std::cin >> n;
    for (int i = n; i >= 1; i--) {
        std::cout << i << ' ';
    }
    std::cout << '\n';
}  

signed main() {
    std::ios::sync_with_stdio(0);
    std::cout.tie(0);   
    std::cin.tie(0);
    
    i64 t = 1; 
    std::cin >> t;
    while (t--) {
        solve();
    }
}

C.小苯的最小整数

我们发现字符串很短,最多就长度为10,暴力模拟即可。

#include<bits/stdc++.h>

using i64 = long long;

void solve() {
    std::string s, ans;
    std::cin >> s;
    ans = s;
    for (int i = 0; i < s.size(); i++) {
        std::string t;
        t = s.substr(i, s.size() - i) + s.substr(0, i);
        if (t < ans) {
            ans = t;
        }
    }
    std::cout << ans << '\n';
}  

signed main() {
    std::ios::sync_with_stdio(0);
    std::cout.tie(0);   
    std::cin.tie(0);
    
    i64 t = 1; 
    std::cin >> t;
    while (t--) {
        solve();
    }
}

D E.小苯的蓄水池

带权并查集,维护联通块大小和联通块中所有数的和,每次查询就直接求平均值即可,合并的时候,用区间右端点的祖宗一直往区间左端点的祖宗上合并即可,每次把当前的“右端点”更新为上一次右端点的祖宗。

#include<bits/stdc++.h>

using i64 = long long;

struct DSU {
    std::vector<i64> f, siz, sum;
    
    DSU() {}
    DSU(int n) {
        init(n);
    }
    
    void init(int n) {
        f.resize(n);
        std::iota(f.begin(), f.end(), 0);
        siz.assign(n, 1);
        sum.resize(n);
    }
    
    int find(int x) {
        while (x != f[x]) {
            x = f[x] = f[f[x]];
        }
        return x;
    }
    
    bool same(int x, int y) {
        return find(x) == find(y);
    }
    
    bool merge(int x, int y) {
        x = find(x);
        y = find(y);
        if (x == y) {
            return false;
        }
        if (x > y) {
            std::swap(x, y);
        }
        siz[x] += siz[y];
        sum[x] += sum[y];
        f[y] = x;
        return true;
    }
    
    int size(int x) {
        return siz[find(x)];
    }
};

void solve() {
    int n, m;
    std::cin >> n >> m;
    
    std::vector<int> a(n + 1);
    for (int i = 1; i <= n; i++) {
        std::cin >> a[i];
    }

    DSU tr(n + 1);
    for (int i = 1; i <= n; i++) {
        tr.sum[i] = a[i];
    }

    while(m--) {
        int op;
        std::cin >> op;
        if (op == 1) {
            int l, r;
            std::cin >> l >> r;
            int fl = tr.find(l);
            int fr = tr.find(r);
            while(fr != fl) {
                tr.merge(fl, fr);
                r = fr - 1;
                fr = tr.find(r);
            }
        }
        else {
            int x;
            std::cin >> x;
            x = tr.find(x);
            std::cout << std::fixed << std::setprecision(6) << tr.sum[x] * 1.0 / tr.siz[x] << '\n';
        }
    }
    // std::cout << 1;
}  

signed main() {
    std::ios::sync_with_stdio(0);
    std::cout.tie(0);   
    std::cin.tie(0);
    
    i64 t = 1; 
    // std::cin >> t;
    while (t--) {
        solve();
    }
}

F. 小苯的字符提前

这个题建议直接去看苯环哥哥的视频题解吧,讲的很清楚,自己也可以手玩一点找找规律,思路大概就是先找到你要找到这个第k小的字符串的开头字母是哪个,比如是a,然后就去找对于每一个a的下一个跟他不同的字母是比他大还是比他小。

#include<bits/stdc++.h>

using i64 = long long;

void solve() {
    int n, k;
    std::cin >> n >> k;
    std::string s;
    std::cin >> s;
    s = ' ' + s;

    std::vector<int> cnt(26, 0);
    for (int i = 1; i <= n; i++) {
        cnt[s[i] - 'a']++;
    }   

    int sum = 0, pos = -1;
    for (int i = 0; i < 26; i++) {
        if (sum + cnt[i] >= k) {
            pos = i;
            break;
        }
        else {
            sum += cnt[i];
        }
    }

    std::vector<int> nxt(n + 1);
    for (int i = n; i >= 1; i--) {
        if (i < n && s[i] == s[i + 1]) {
            nxt[i] = nxt[i + 1];
        }
        else {
            nxt[i] = i + 1;
        }
    }

    std::deque<int> q;
    for (int i = n; i >= 1; i--) {
        if ((s[i] - 'a') != pos) continue;
        int x = nxt[i];
        if (x <= n && s[i] < s[x]) {
            q.emplace_back(i);
        }
        else {
            q.emplace_front(i);
        }
    }

    for (int i = 1; i < k - sum; i++) {
        q.pop_front();
    }
    std::cout << s[q.front()] << s.substr(1, q.front() - 1) << s.substr(q.front() + 1) << '\n';
}

signed main() {
    std::ios::sync_with_stdio(0);
    std::cout.tie(0);   
    std::cin.tie(0);
    
    i64 t = 1; 
    std::cin >> t;
    while (t--) {
        solve();
    }
}