Educational Codeforces Round 108 (Rated for Div. 2) (A思维,Bmath,C前缀和,D枚举)

1519A. Red and Blue Beans

问题简述

给定 r 个红豆,b 个蓝豆,差值 d ,要求我们进行为红蓝豆分组,使得红豆和蓝豆绝对值差值不大于 d ,即:一个红豆最多与 d+1 个蓝豆组合,反之亦然

问题分析

设数量小的豆子为 x ,数量多的豆子为 y 所以满足 yx+x·d 输出 YES

代码解决

using ll = long long;
void solve() {
    ll r, b, d;
    cin >> r >> b >> d;
    if (r < b) swap(r, b);
    cout << (b + b * d >= r ? "YES\n" : "NO\n");
}

1519B. The Cake Is a Lie

问题简述

求从(1,1) 移动至 (n,m) 的 Cost是否等于 k,每一步的代价:(x,y)(x+1,y) 代价为 y(x,y)(x,y+1) 的代价为 x

问题分析

可以通过DP或者数学的方法解决

这里贴一下暴力解法 DFS

int n, m, k;
ll cnt = 0;
void dfs(int x, int y, int val) {
    if (x == n && y == m) {
        cnt = val;
        return;
    }
    if (x > n || y > m) return;
    if (x < n)
        dfs(x + 1, y, val + y);
    else
        dfs(x, y + 1, val + x);
}
void solve() {
    cnt = 0;
    cin >> n >> m >> k;
    dfs(1, 1, 0);
    cout << (cnt == k ? "YES\n" : "NO\n");
}

math:k=(m1)+m(n1) 输出 YES

using ll = long long;
void solve() {
    ll n, m, k;
    cin >> n >> m >> k;
    cout << (k == (m - 1) + m * (n - 1) ? "YES\n" : "NO\n");
}

1519C. Berland Regional

问题简述

某地方举办XCPC区域赛, n 个学生,分别来自 ui 且每人的编程能力 si ,如果限定每个队伍必须 k 人,那么学校会安排 si 更大的人组队,并且每个学院可以派出多个队伍且保证每个队友刚好 k 人,当 k=1,2,...n 时,求出所有学校参赛人的 si ,当人数不够 k 时战力和为 0 .

问题分析

把每个学生存到对应的学校,并按照从大到小降序存进数组 u[] 且对每个学校的该大小位size的数组进行前缀和s[],每个学校对 ansk 的贡献是前 size-k%size(size/k*k) 个的前缀和

using ll    = long long;
const int N = 2e5 + 7;
set<ll> st;
vector<ll> u[N];
bool cmp(pair<ll, ll> a, pair<ll, ll> b) { return a.first > b.first; }
void solve() {
    int n;
    cin >> n;
    vector<pair<ll, ll>> p(n);
    vector<ll> cnt(n + 2, 0);
    st.clear();
    for (int i = 0; i <= n; ++i) u[i].clear();
    for (int i = 0; i < n; ++i) cin >> p[i].second, st.insert(p[i].second);
    for (int i = 0; i < n; ++i) cin >> p[i].first;
    sort(p.begin(), p.end(), cmp);
    for (int i = 0; i < n; ++i) u[p[i].second].push_back(p[i].first);
    for (auto i : st) {
        int siz = u[i].size();
        for (int j = 1; j < siz; j++) u[i][j] += u[i][j - 1];
        for (int j = 1; j <= siz; j++) cnt[j] += u[i][siz - 1 - siz % j]; //关键是这里处理ans[]
    }
    for (int i = 1; i <= n; i++) cout << cnt[i] << " ";
    cout << endl;
}

1519D. Maximum Sum of Products

问题简述

至多可以反转一次 a[] ,问最大的 aibi

问题分析

T=2s,n=5000,直接枚举所有情况,所以考虑 aibi 的前缀和,枚举中点,且考虑翻转的长度奇偶,把翻转的 [l,r] 和 [l-1,r+1] 的式子展开发展不同点只有a[l1]b[r+1]+a[r+1]b[l1] ,左右两端用前缀和求和即可

using ll = long long;
ll a[5005], b[5005], s[5005], ans = 0;
int n;
void run1(int x) { //翻转长度位奇数
    ll res = 0;
    for (int l = x, r = x; l >= 1 && r <= n; l--, r++) {
        if (l == r) res += a[l] * b[l];
        else
            res += a[l] * b[r] + a[r] * b[l];
        ans = max(ans, res + s[l - 1] + s[n] - s[r]);
    }
}
void run2(int x) { //翻转长度位偶数
    ll res = 0;
    for (int l = x, r = x + 1; l >= 1 && r <= n; l--, r++) {
        if (l == r) res += a[l] * b[l];
        else
            res += a[l] * b[r] + a[r] * b[l];
        ans = max(ans, res + s[l - 1] + s[n] - s[r]);
    }
}
void solve() {
    cin >> n;
    for (int i = 1; i <= n; i++) cin >> a[i];
    for (int j = 1; j <= n; j++) cin >> b[j];
    for (int i = 1; i <= n; i++) s[i] = s[i - 1] + a[i] * b[i];
    for (int i = 1; i <= n; i++) run1(i); //翻转长度位奇数
    for (int i = 1; i <= n; i++) run2(i); //翻转长度位偶数
    ans = max(ans, s[n]);                 //特判一下原来不翻转
    cout << ans;
}
posted @   RioTian  阅读(99)  评论(0编辑  收藏  举报
编辑推荐:
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 没有源码,如何修改代码逻辑?
· 一个奇形怪状的面试题:Bean中的CHM要不要加volatile?
阅读排行:
· 分享4款.NET开源、免费、实用的商城系统
· Obsidian + DeepSeek:免费 AI 助力你的知识管理,让你的笔记飞起来!
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· 全程不用写代码,我用AI程序员写了一个飞机大战
点击右上角即可分享
微信分享提示

📖目录