230606蓝桥训练

重现

A-数数

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

int main(){
    string s;
    set<char> cnt;
    cin >> s;
    for( auto c : s )
        cnt.insert(c);
    cout << cnt.size() << "\n";
    return 0;
}

B-二进制?十进制!

#include <bits/stdc++.h>

using namespace std;

#define int long long

int32_t main() {
    int a, b;
    vector<int> c;
    cin >> a >> b;
    if (a < b) swap(a, b);

    while (a) c.push_back(a & 1), a >>= 1;

    for (int i = 0; b > 0 && i < c.size(); i++)
        c[i] += b & 1, b >>= 1;
    reverse(c.begin(), c.end());
    for (auto i: c)
        cout << i;
}

C-夹娃娃

#include <bits/stdc++.h>

using namespace std;

#define int long long

int32_t main() {
    ios::sync_with_stdio(false) , cin.tie(nullptr) , cout.tie(nullptr);

    int n , k;
    cin >> n >> k;
    vector<int> a( n+1 );
    for( int i = 1 ; i <= n ; i ++ )
        cin >> a[i] , a[i] += a[i-1];
    for( int l , r ; k ; k -- ){
        cin >> l >> r;
        cout << a[r] - a[l-1] << "\n";
    }
}

D-子序列

贪心的向肯定是开头加一个a或则结尾加一个b两种。这注意题会爆long long

#include <bits/stdc++.h>

using namespace std;

#define int unsigned long long

int32_t main() {
    ios::sync_with_stdio(false), cin.tie(nullptr), cout.tie(nullptr);
    string x, y;
    cin >> x;
    y = x + "b", x = "a" + x;
    int f = 0, g = 0, ans = 0, res = 0, n = x.size();
    for (int i = 0; i < n; i++) {
        if (x[i] == 'a') f++;
        else ans += f * (f - 1) / 2;

        if (y[i] == 'a') g++;
        else res += g * (g - 1) / 2;
    }
    cout << max(ans, res);
}

E-小L的编辑器

list模拟一下

#include <bits/stdc++.h>

using namespace std;

#define int long long

int n, res = 0;

int32_t main() {
    ios::sync_with_stdio(false), cin.tie(nullptr), cout.tie(nullptr);
    list<char> res;
    auto it = res.begin();
    string s, t;
    cin >> s >> t;
    int n = s.size();

    for (int i = 0; i < n; i++) {
        res.insert(it, s[i]);
        if( t[i] == 'L' ) it --;
    }
    for( auto i : res )
        cout << i;
}

F-答题卡

dp写法。\(f[i]\)表示$i\times i \(的答题卡的方案数。考虑第一列的放置情况。如果放在\)(1,1)\(则考虑剩下\)i-1\(列,如果放\)(1,x)\(,这相当于和\)(x,1)\(交换位置,还要考虑剩下\)i-2\(列,这里\)x\(的取值是\)i-1\(。所以\)f[i]=f[i-1]+(i-1)\times f[i-2]$

#include <bits/stdc++.h>

using namespace std;

#define int long long

const int mod = 1e9+7;

int32_t main() {
    ios::sync_with_stdio(false), cin.tie(nullptr), cout.tie(nullptr);
    int n;
    cin >> n;
    vector<int> f(n+1);
    f[0] = f[1] = 1;
    for( int i = 2 ; i <= n ; i ++ )
        f[i] = f[i-1] + (i-1) * f[i-2] , f[i] %= mod;
    cout << f[n];
}

G-牛牛的数列

首先要找的\(a_i \oplus s\)的最大值,所以令\(b_i=a_i\oplus s\)然后用 st 表维护一下最值即可。

这里要找\(k\)其实没有用,找到\(b_i\)后求出\(a_i\)就好了。然后\(S\)可以前缀异或和计算。

\(W\)其实可以自己从高位枚举每一个二进制位选或不选即可。

#include <bits/stdc++.h>

using namespace std;

int read() {
    int x = 0, ch = getchar();
    while (ch < '0' || ch > '9') ch = getchar();
    while (ch >= '0' && ch <= '9') x = (x << 3) + (x << 1) + ch - '0', ch = getchar();
    return x;
}

int32_t main() {
    int n = read(), q = read(), s = read(), w = read();
    vector<int> b(n + 1), c(n + 1);
    for (int i = 1, x; i <= n; i++)
        x = read(), b[i] = x ^ s, c[i] = c[i - 1] ^ x;
    const int logN = log2(n) + 1;


    vector<int> p(1);
    p[0] = 1;
    while (p.size() < logN || p.back() < w)
        p.push_back(p.back() * 2ll);

    vector<vector<int>> f(n + 1, vector<int>(logN, 0));
    for (int i = 1; i <= n; i++) f[i][0] = b[i];
    for (int j = 1; j < logN; j++)
        for (int i = 1; i + p[j - 1] <= n; i++)
            f[i][j] = max(f[i][j - 1], f[i + p[j - 1]][j - 1]);

    auto getMax = [f, p](int l, int r) {
        int s = r - l + 1, j = log2(s);
        return max(f[l][j], f[r - p[j] + 1][j]);
    };
    for (int l, r, aj, S, m; q; q--) {
        l = read(), r = read();
        aj = getMax(l, r) ^ s, S = c[r] ^ c[l - 1] ^ aj;
        for (int i = p.size() - 1, m = w; i >= 0; i--) {
            if (p[i] > m || S & p[i]) continue;
            S ^= p[i], m -= p[i];
        }
        printf("%d\n", S);

    }
    return 0;

}

H-小y的旅行

采取了一种贪心的思路,首先把和前\(k\)个点无关的边全部都加进去,然后把枚举剩下的边,用并查集判断如果加边后成环了就不加边,否则就加边。

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

struct dsu{
    int n;
    vector<int> fa;
    dsu( int n = 0 ) : n(n) , fa( n + 1 , -1 ) {};

    int getfa( int x ){
        if( fa[x] < 0 ) return x;
        return fa[x] = getfa(fa[x]);
    }

    bool check( int & x , int &y ){
        x = getfa(x) , y = getfa(y);
        return x == y;
    }

    bool merge( int x , int y ){
        if( check(x,y) ) return false;
        if( fa[x] > fa[y] ) swap( x , y );
        fa[x] += fa[y] , fa[y] = x;
        return true;
    }
};

int main(){
    int n , m , k;
    cin >> n >> m >> k;
    vector<pair<int,int>> e;
    dsu d(n);
    for( int x , y ; m; m--){
        cin >> x >> y;
        if( x > y ) swap( x , y );
        if( x <= k ) e.emplace_back( x , y );
        else d.merge( x , y );
    }
    int res = 0;
    for( auto [x,y] : e )
        if( d.merge( x , y ) == false ) res ++;
    cout << res;
}
posted @ 2023-06-06 21:24  PHarr  阅读(6)  评论(0编辑  收藏  举报