2024年码蹄杯专科组第一场初赛 解题报告 | 珂学家


前言

在这里插入图片描述


题解

这是码蹄杯2024年专科组的第一场初赛,整体下来相对比较简单。

有一道0-1分数规划(拔河)不错,一道模拟题(云顶之奕)还行。


拔河

难度: 钻石

思路: 0-1分数规划 + 前缀和单调队列优化

板子题,如果之前没做过类似的0-1分数规划题,那就很难了,这题可以作为本场的压轴题。

一般对于子数组的平均数最值问题

  • 采用二分思路
  • 然后把题转化为0-1判定问题

对于check的核心逻辑

相当于重构数组 b r r [ i ] = a r r [ i ] − a v g brr[i]=arr[i] - avg brr[i]=arr[i]avg,

存在一个子区间

∑ t = i t = j b r r [ t ] > = 0 , j − i + 1 ≥ k \sum_{t=i}^{t=j} brr[t] >= 0, j - i + 1 \ge k t=it=jbrr[t]>=0,ji+1k

#include<bits/stdc++.h> 

using namespace std;

int main( )
{
    // 0-1分数规划
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    cout.tie(nullptr);

    int n, f;
    cin >> n >> f;
    vector<int> arr(n);
    for (int &x: arr) cin >> x;

    // 核心check逻辑
    function<bool(double)> check = [&](double avg) {
        double acc = 0;
        for (int i = 0; i < f - 1; i++) {
            acc += (arr[i] - avg);
        }
        // 保证窗口大于f
        // 单调队列优化,保持前缀和的最小值即可
        double preF = 0;
        double preMin = 0;
        for (int i = f - 1; i < n; i++) {
            acc += (arr[i] - avg);
            if (acc - preMin >= 0) return true;
            preF += (arr[i - f + 1] - avg);
            preMin = min(preMin, preF);
        }
        return false;
    };

    // 二分
    double l = 0, r = 2000;
    while (r - l > 1e-6) {
        double m = (l + r) / 2.0;
        if (check(m)) {
            l = m;
        } else {
            r = m;
        }
    }    
    cout << (int)(r * 1000) << endl;
    return 0;
}

云顶之奕

难度: 钻石

思路: 模拟题

它的题意,有些地方还是需要加强

  • 最多8个位子,如果新加入,不能产生合并,就会被忽略

比如当前为{1,2,3,4,5,10,20,30}, 此时新来一个1,因为8位子满了,就会被忽略

#include<bits/stdc++.h> 

using namespace std;

struct Game {
    int cap;
    map<int, int> hp;

    Game() : cap(0) {}
    void add(int v) {
        if (cap < 8 || (v < 100 && (hp[v] + 1) % 3 == 0)) {
            cap += 1;
            hp[v]++;
            while (v < 100 && hp[v] % 3 == 0) {
                hp[v] = 0;
                hp[v * 10]++;
                v = v * 10;
                cap -= 2;
            }
        }
    }

    int maxValue() {
        int r = 0;
        for (auto &[k, v] : hp) {
            if (v > 0) r = max(r, k);
        }
        return r;
    }
};

int main( )
{
    Game game;
    // 备战席,固定为8
    for (int i = 0; i < 8; i++) {
        int v;
        cin >> v;
        game.add(v);
    }
    // 备选席(流水)
    int n;
    cin >> n;
    for (int i = 0; i < n; i++) {
        int v;
        cin >> v;
        game.add(v);
    }

    int m;
    cin >> m;
    if (game.maxValue() >= m) {
        cout << "YES YES YES" << endl;
    } else {
        cout << "NO NO NO" << endl;
    }
    
    return 0;
}

写在最后

在这里插入图片描述

  • 9
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
第六届传智杯B初赛是传智播客举办的一次IT技术竞赛的初赛阶段,旨在选拔出各高校优秀的程序设计人才。该比赛中,参赛者将面临多道编程题目,通过编写程序解决问题来展示他们的技术水平和创新能力。 在初赛中,参赛者需要在规定的时间内完成多道程序设计题目。这些题目可能涉及数据结构、算法、网络通信等方面的知识,要求参赛者具备扎实的编程基础和解决实际问题的能力。 参赛者需要在规定的时间内完成编程题目,并提交给评委进行评分。评委会根据答案的正确性、效率、代码的可读性等方面对参赛者的作品进行综合评判。最终,得分高的参赛者将进入下一轮比赛。 第六届传智杯B初赛的目的是为了选拔出具备优秀编程能力的学生,为他们提供一个展示才华、学习交流的平台。参赛者不仅可以通过比赛锻炼自己的编程技巧,还可以结识其他优秀的参赛者,相互学习、切磋技艺。 在比赛过程中,参赛者还可以通过与其他选手交流,了解各种不同的编程思路和解题方法,不断提高自己的编程水平。同时,参赛者还有机会与业界的专家学者进行交流,了解最新的技术动态和发展趋势。 总之,第六届传智杯B初赛是一次很有意义的编程竞赛,为各大高校的IT人才选拔提供了一次难得的机会。通过比赛,参赛者可以展现自己的才华,提升技术水平,同时也可以与其他优秀选手进行交流,共同进步。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值