牛客春招刷题训练营-2025.5.30题解

/ 活动地址: 牛客春招刷题训练营 - 编程打卡活动

简单题 藻类植物

题面给出了递推式,直接根据递推式循环 次计算 即可。

#include <bits/stdc++.h>
using namespace std;
int main() {
    int r, d, x;
    cin >> r >> d >> x;
    for (int i = 0; i < 10; i++) {
        x = r * x - d;
        cout << x << '\n';
    }
    return 0;
}

中等题 小红的蛋糕切割

首先需要二维前缀和维护一段矩阵的和。
设整个矩阵的和为 ,如果知道了正方形内的和 ,则美味度之差为
首先可以想到枚举正方形左上角的点,再暴力枚举正方形的边长。
该算法时间复杂度为 ,因为本题bug,可以通过。
考虑优化:
仍然枚举正方形左上角的点,但是在枚举边长时,因为 ,所以 对于边长 单调递增, 对于 应当是一个单峰函数,所以可以三分 来寻找这个函数的极值。
或者可以把绝对值去掉,这样就变成了严格单调递减的函数,可以二分最接近 的点。
时间复杂度为

#include <bits/stdc++.h>
using namespace std;
using ll = long long;
ll a[1003][1003];
ll pre[1003][1003];
int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    int n, m;
    cin >> n >> m;
    for (int i = 1; i <= n; i++)
        for (int j = 1; j <= m; j++)
            cin >> a[i][j];
    for (int i = 1; i <= n; i++)
        for (int j = 1; j <= m; j++)
            pre[i][j] = pre[i - 1][j] + pre[i][j - 1] - pre[i - 1][j - 1] + a[i][j];
    ll ans = 8e18;
    ll sum = pre[n][m];
    for (int i = 1; i <= n; i++) {
        for (int j = 1; j <= m; j++) {
            int l = 1, r = min(n - i + 1, m - j + 1);
            auto calc = [&](int x) -> ll {
                return abs(sum - 2 * (pre[i + x - 1][j + x - 1] - pre[i + x - 1][j - 1] - pre[i - 1][j + x - 1] + pre[i - 1][j - 1]));
            };
            while (l < r) {
                if (r - l <= 2) {
                    for (int k = l; k <= r; k++)
                        ans = min(ans, calc(k));
                    break;
                }
                int mid1 = (l + r) / 2;
                int mid2 = mid1 + 1;
                ll ans1 = calc(mid1);
                ll ans2 = calc(mid2);
                if (ans1 == ans2) {
                    l = mid1;
                    r = mid2;
                } else if (ans1 < ans2) {
                    r = mid2;
                } else {
                    l = mid1;
                }
            }
        }
    }
    cout << ans << '\n';
    return 0;
}

困难题 【模板】整数域三分

三分主要用来寻找单峰函数的最值。
本题的 是一个存在最小值的单峰函数。
三分过程中,首先取两个点
如果 ,则
如果 ,则
如果 ,则
时,取中点比较麻烦,直接暴力计算该区间内所有数的函数值即可。
时间复杂度

#include <bits/stdc++.h>
using namespace std;
using ll = long long;
struct line {
    int k, a, b;
};
void solve() {
    int n, l, r;
    cin >> n >> l >> r;
    ll ans = 8e18;
    vector<line> f(n);
    for (int i = 0; i < n; i++)cin >> f[i].k >> f[i].a >> f[i].b;
    auto calc = [&](int x) -> ll {
        ll sum = 0;
        for (int i = 0; i < n; i++)
            sum += abs(1ll * f[i].k * x + f[i].a) + f[i].b;
        return sum;
    };
    while (l < r) {
        if (r - l <= 2) {
            for (int i = l; i <= r; i++)
                ans = min(ans, calc(i));
            break;
        }
        int mid1 = l + (r - l) / 3;
        int mid2 = l + (r - l) * 2 / 3;
        ll ans1 = calc(mid1);
        ll ans2 = calc(mid2);
        if (ans1 == ans2) {
            l = mid1;
            r = mid2;
        } else if (ans1 < ans2)r = mid2;
        else l = mid1;
    }
    cout << ans << '\n';
}
int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    int t;
    cin >> t;
    while (t--)solve();
    return 0;
}
#牛客春招刷题训练营#
全部评论
1 回复 分享
发布于 06-01 20:12 辽宁
点赞 回复 分享
发布于 06-01 21:10 湖北
关注73喵,关注73谢谢喵
点赞 回复 分享
发布于 06-01 21:01 山东
点赞 回复 分享
发布于 06-01 20:51 辽宁
点赞 回复 分享
发布于 06-01 20:30 辽宁
点赞 回复 分享
发布于 06-01 20:22 重庆
点赞 回复 分享
发布于 06-01 20:17 江西
已老实
点赞 回复 分享
发布于 06-01 20:00 江西
点赞 回复 分享
发布于 06-01 19:50 河北
点赞 回复 分享
发布于 06-01 19:47 北京

相关推荐

Frank_zhang:有的兄弟
点赞 评论 收藏
分享
评论
1
收藏
分享

创作者周榜

更多
牛客网
牛客企业服务