【问题标题】:A better algorithm for a "Tournament" [duplicate]“锦标赛”的更好算法[重复]
【发布时间】:2014-11-28 14:57:27
【问题描述】:

我有一个问题。几天以来我一直在为 ZCO 做准备,我遇到了一个非常简单的问题,我无法在 3 秒的时间限制内解决。问题来了:

N 支球队参加了火星上的板球联赛,每支球队 一对不同的球队互相比赛一次。因此,有 总共有 (N × (N1))/2 个匹配项。专家分配了力量 每个团队,一个正整数。奇怪的是,火星人喜欢 单边比赛,一场比赛获得的广告收入为 两者实力之差的绝对值 火柴。给定 N 支队伍的实力,求总数 从所有比赛中获得的广告收入。

例如,假设 N 为 4,团队 1、2、3 的团队实力, 和 4 分别是 3、10、3 和 5。然后是广告收入 6场比赛的结果如下:

7、0、2、7、5、2

因此总广告收入为 23。

样本输入 4 3 10 3 5 样本输出 23 测试数据 在所有子任务中, 每支队伍的实力是介于 1 和 1,000 之间的整数。

子任务 1(30 分):2 ≤ N ≤ 1,000。
子任务 2(70 分):2 ≤ N ≤ 200,000。

限制

时间限制:3秒

内存限制:64 MB

所以,我选择了一种简单的算法,该算法可以扫描并找出每个团队的广告收入与之前的所有其他团队相对应。这相当于 O(n^2) 未能通过子任务 2。我认为不可能对此进行改进,有人可以帮助我吗?

附:虽然它没有帮助,但这是我当前的 C 代码:

#include <stdio.h>

int main(void)
{
    long long int n, i, j;
    scanf("%lld", &n);
    long long int A[n], strength = 0;
    for(i = 0;i < n;i++)
    {
        scanf("%lld", &A[i]);
        for(j = i;j >= 0;j--)
        {
            strength += A[i] > A[j] ? A[i] - A[j] : A[j] - A[i];
        }
    }
    printf("%lld\n", strength);
    return 0;
}

【问题讨论】:

    标签: c performance algorithm


    【解决方案1】:

    假设我们有 10 支队伍,按从强到弱分别称为 A、B、C、...、J。让我们看看 A 和 J 之间的匹配。它有一个有趣的属性:该匹配的收入与其他两个匹配 AB 和 BJ 的收入之和相同。哦,还有 AC 和 CJ。而且...哇,通过将 AJ 乘以 9,我们得到所有匹配 A 或 J 的收入总和!现在我们只剩下8支球队了。让我们看一下 B 对 I 的比赛。它有一个有趣的性质……数学不是很棒吗?

    【讨论】:

    • 为什么要做社区维基?这是当之无愧的代表:)
    • 哇。我被你的观察震惊了。但是你能在数学上证明这一点吗?我的意思是,这是一个不正常的观察结果。
    • 我来自哪里,这个观察算作一个证明,尽可能数学化。您可能希望将 10 替换为 N 以获得最大的严格性。现在,如果您是 Bourbaki 成员或其他人,您可能仍希望有点更加严格,但如果您是 Bourbaki 成员,您通常不会就 SO 寻求建议。
    猜你喜欢
    • 1970-01-01
    • 2012-05-17
    • 2014-04-23
    • 2010-12-13
    • 2016-10-17
    • 2013-11-18
    • 1970-01-01
    • 2022-01-24
    • 2017-09-01
    相关资源
    最近更新 更多