【题解】牛客2025年儿童节比赛 E、F

E. 别人家的孩子

本题考查程序设计基础。

对于所有 ,求出 、……、 的最大值,输出即可。

#include <iostream>

using namespace std;

const int N = 100;

int a[N][N], b[N];

int main()
{
    int n = 0, m = 0;
    cin >> n >> m;
    for (int i = 0; i < n; ++i)
        for (int j = 0; j < m; ++j)
            cin >> a[i][j];
    for (int i = 0; i < n; ++i)
        for (int j = 0; j < m; ++j)
            if (a[i][j] > b[j])
                b[j] = a[i][j];
    cout << b[0];
    for (int j = 1; j < m; ++j)
        cout << ' ' << b[j];
    cout << '\n';
}

F. 年龄

我们把上述条件转化一下。本题实际上要求我们计算,有多少个整数四元组 满足 能被 整除, 能被 整除,,且 。也就是说,要在 以内选出两个不同的倍数对,其两个元素对应差值相等,求选法的个数。

为了解决这个问题,我们先计算出在 以内所有满足 能被 整除的整数对 。根据调和数列求和的积分估计,这样的整数对有 个。

然后,创建一个数组 ,其中 表示上述整数对中,满足 的整数对 的个数。对于上面计算出的每个整数对 ,都记录 的差值 ,令 增加 。这一步的目的是按元素之差给倍数对分组。

于是问题转化为:在同一组内选出两个不同的元素,求选法个数。

因为 的范围是 (含边界),所以根据组合计数原理,答案即为

时间复杂度 ,空间复杂度

#include <iostream>
#include <vector>

using namespace std;
using LL = long long;

int main()
{
    LL m = 0, result = 0;
    cin >> m;
    vector<LL> d(m);
    for (LL b = 1; b <= m; ++b)
        for (LL p = 1; p <= m / b; ++p)
        {
            LL a = 0;
            a = b * p;
            ++d[a - b];
        }
    for (LL i = 0; i < m; ++i)
        result += d[i] * (d[i] - 1) / 2;
    cout << result << '\n';
}
全部评论
在看大家代码时,发现有人把 for (LL p = 1; p <= m / b; ++p) 写成 for (LL a = b; a <= m; a += b)。我思考了一下,发现后者写法更好。学到了!
1 回复 分享
发布于 06-02 07:58 安徽
刚刚更新了代码
1 回复 分享
发布于 06-01 21:10 安徽
F 是唯一一个正经 OI 题,泪目了。
1 回复 分享
发布于 06-01 21:09 重庆
这题好难
点赞 回复 分享
发布于 06-02 19:36 辽宁
F题对xxs真的友好吗(
点赞 回复 分享
发布于 06-01 21:07 湖北

相关推荐

评论
3
收藏
分享

创作者周榜

更多
牛客网
牛客企业服务