• 2021“MINIEYE杯”中国大学生算法设计超级联赛(5)


    2021“MINIEYE杯”中国大学生算法设计超级联赛(5)

    1003.VC Is All You Need

    • 题意

    给你一个k维平面,问你是不是随意放n个点都能用k-1条线分隔开

    • 思路

    emmmm, 思考一下, n > k + 1都是不行的。。

    code:

    void solve(){
        ll n,k;
        cin >> n >> k;
        if(n > k+1){
            cout << "No" << endl;
        }else cout << "Yes" << endl;
    }
    

    1004.Another String

    • 题意

    给定n,k和字符串s, 让你求出从(1 o i)(i + 1 o n)中任意挑选两个子字符串,要求长度相同,并且着一堆字符串中最多有k个字符不同,问你有多少对这样的子字符串

    • 思路

    暴力+双指针,求出f[i][j]表示i,j位置为两字符串的左端点,满足要求的最大长度,然后双指针枚举长度。
    在纸上模拟一边在通过一些推导可以发现每个位置的贡献是固定的,用差分+两次前缀和便可计算答案。。

    code:

    int f[N][N];
    char str[N];
    int ans[N];
    
    void solve(){
        int n,k;
        cin >> n >> k;
        cin >> (str + 1);
        // 枚举右端点
        for(int st = 2;st <= n;st ++) {
            int len = 0;
            int dif = 0;
            // 固定左右端点长度,往后双指针枚举
            for(int i = 1, j = st;j <= n;j ++,i ++) {
                while(dif <= k) {
                    dif += str[i + len] != str[j + len];
                    len ++; 
                }
                f[i][j] = min(len - 1, min(j - i, n - j + 1));
                len --;dif -= (str[i] != str[j]);
            }
        }
        memset(ans,0,sizeof ans);
    
        for(int i = 1;i <= n;i ++) {
            for(int j = i + 1;j <= n;j ++) {
                ans[i] ++;
                ans[i + f[i][j]] --;
                ans[j] -= f[i][j];
                ans[j + 1] += f[i][j];
            }
        }
        for(int i = 1;i <= n;i ++) ans[i] += ans[i - 1];
        for(int i = 1;i <= n;i ++) {
            ans[i] += ans[i - 1];
            if(i != n) cout << ans[i] << endl;
        }
    }
    

    1006.Cute Tree

    • 题意

    给出一个类三叉树的构造方法,让你输出它能建立的节点个数

    • 思路

    按着图上的代码打就行了,又不会超时

    code:

    
    int a[N];
    int tot;
    
    void build(int id,int l,int r) {
        tot ++;
        id = tot;
        if(l == r) {
            return;
        }
        if(r - l + 1 == 1) {
            int mid = l + r >> 1;
            tot += 2;
            return;
        }else {
            int B = l + ceil((r - l + 1) / 3.0) - 1;
            int C = B + r >> 1;
            if(B >= l)
            build(id,l,B);
            if(C >= B + 1)
            build(id,B + 1,C);
            if(r >= C+1);
            build(id,C+1,r);
        }
    }
    
    void solve(){
        tot = 0;
        int n;
        cin >> n;
        for(int i = 1;i <= n;i ++) cin >> a[i];
        build(1,1,n);
        cout << tot << endl;
    }
    
    

    1007.Banzhuan

    • 题意

    给一个(n * n * n)的立方体空间, 你只能用1立方体积的小立方块去填,小立方体放在一个位置,那么它的价值就是(x * y^2 * z), 并且,如果你防止的地方的底部(z轴)为空,那么它会一直往下掉。

    • 思路

    what
    然后, dddd , 套公式了。。

    code:

    const ll mod = 1e9 + 7;
    ll qpow(ll a, ll b, ll mod){
        ll ans = 1;
        while(b){
            if(b & 1)ans=ans*a%mod;
            b>>=1;
            a=a*a%mod;
        }
        return ans;
    }
    void solve(){
        ll n;
        cin >> n;
        n %= mod;
        ll res = (n%mod*(n+1)%mod*qpow(2,mod-2,mod)%mod)%mod;
        // cnt计算侧面的立方体
        ll cnt = (res%mod*(n%mod*(n+1)%mod*(2*n+1)%mod*qpow(6,mod-2,mod)%mod-1+mod)%mod)%mod;
        // cnt1计算正面
        ll cnt1 = (res%mod-1+mod)%mod*(res%mod)%mod;
        // cnt2底面
        ll cnt2 = ((res%mod)%mod*(n%mod*(n+1)%mod*(2*n+1)%mod)%mod*qpow(6,mod-2,mod)%mod)%mod;
        ll ans = (cnt+cnt1+cnt2 - (res-1+mod)%mod - ((n%mod*(n+1)%mod*(2*n+1)%mod*qpow(6,mod-2,mod)%mod-1+mod)+1ll*2*mod)%mod+ 1ll*5*mod)%mod;//最小值
        ll ans1 =  (n%mod*n%mod*cnt2%mod)%mod; // 最大值
        cout << ans << endl;
        cout << ans1 << endl;
    }
    

    1009.Array

    • 题意

    给出一个长度为n的序列,满足一对(l,r)及((a_l,a_{l+1}···,a_r))之中,众数出现的次数严格大于其他非众数出现的次数

    • 思路

    写了半天的线段树疯狂t,给出的数据倒是能过,我人已傻,占坑

    code:

  • 相关阅读:
    C++使用静态类成员时出现的一个问题
    C++中的const_cast
    【位运算与嵌入式编程】
    电压取反电路
    bzoj4769
    初赛
    noip2011day2
    uva1252
    codeforces 703d
    poj[1734]
  • 原文地址:https://www.cnblogs.com/darker-wxl/p/15095835.html
Copyright © 2020-2023  润新知