繁体   English   中英

不明白 Codility CountDiv 解决方案是如何正确的

[英]Don't understand how Codility CountDiv solution is correct

Codility CountDiv 练习

给定范围 A..B 和值 K,返回范围内可被 K 整除的值的数量。

给出的例子是 A = 6, B = 11 和 K = 2。在 6 到 11 的范围内,能被 2 整除的数是 6、8 和 10,所以答案是 3。所需的解决方案必须是 O(1) - 所以需要一个简单的计算。

您可以假设 A 和 B 的范围是 0..2,000,000,000,K 是 1..2,000,000,000 并且 0 <= A <= B。

得分为 100% 的公认解决方案如下:

int solution(int A, int B, int K)
{
    int inclusive = ((A%K)==0) ? 1 : 0;
    return (B/K) - (A/K) + inclusive;
}

我感到困惑的是,当我使用输入 A=0、B=0 和 K=1 测试此解决方案时,结果是 1? 我原以为在 0 到 0 的范围内,可被 1 整除的值的数量是... 0!

我认为这是一个错误,只有在 A 非零时才应设置 A 的包含值的 +1。

所以我提交了以下解决方案(测试 A 非零):

int solution(int A, int B, int K)
{
    int inclusive = (A && (A%K)==0) ? 1 : 0;
    return (B/K) - (A/K) + inclusive;
}

但这仅获得了 62%(50% 的正确率和 75% 的性能)。 它失败的一些测试用例是:

  • A = 0,B = 1,K = 11 - 得到 0,预期为 1
  • A = 0, B = MAXINT, K in {1,MAXINT},得到 2000000000,预期为 2000000001

有人可以解释一下吗?

对于所有允许的K (非零),值0可被K整除。 零没有什么特别之处。 可整除的定义是指除之后没有余数。

范围包括:在00范围内有 1 个值:值0本身。 所有值都可以被1整除,因此结果确实是1值。

请注意,建议的代码是多余的:

int inclusive = ((A%K)==0) ? 1 : 0; 相当于int inclusive = (A%K)==0; . 它可以进一步简化为int inclusive = !(A%K); 并且完整的解决方案变成了一个单线:

int solution(int A, int B, int K) { return B/K - A/K + !(A%K); }

这是一个只有 2 个分区的变体:

int solution(int A, int B, int K) { return B/K - (A ? (A-1)/K : -1); }

这是一个得分为 100/100 的 C++ 解决方案

int solution(int A, int B, int K) {
    return B / K - A / K + (A % K == 0 ? 1 : 0);
}

它返回区间 [0, B] 中的倍数减去区间 [0, A] 中的倍数 - 得到区间 (A, B] 中的倍数 - 并在 A 中添加倍数 if A是一个倍数。

就我而言,我只是做了以下数学运算:

(B - A)/K + (A/K)

在与之前解释的相同情况下,这个 + (A/K) 非常棘手,因为一些愚蠢的输入,如 A=0,B=0 等。然后,对于这些情况,我做了一个处理,我称之为调整。

有代码:

class Solution {
public int solution(int startingFrom, int endingAt, int divisibleBy) {

    double adjustment = startingFrom % divisibleBy == 0 || endingAt % divisibleBy == 0 ? 1 : ((double) startingFrom < divisibleBy) ? (double) startingFrom / divisibleBy : 0;

    return (int) ( ((double) endingAt - startingFrom) / (divisibleBy) + adjustment);
}

}

Java 代码 100/100。

https://app.codility.com/demo/results/trainingS96J5R-NTC/

我在 javascript 中的解决方案

function solution (A, B, K) {
  if (B - A === 0 && B == 0) return 1;
  if (B - A === 0 && B > K && B % K === 0 ) return 1;
  if (B - A === 0 && B > K && B % K > 0 ) return 0;
  if (B < K) return 0;

  return Math.floor(B/K) - Math.floor((A - 1)/K);
}

更多在这里https://github.com/mazeeblanke/codilityLessons

我认为我的解决方案非常直接且不言自明。 100/100

 function solution(min, max, divider) { let minRemainder = min % divider; let minQuotient = Math.floor(min / divider); let maxQuotient = Math.floor(max / divider); const includeFirstNum = minRemainder === 0; const bonus = includeFirstNum ? 1 : 0; const res = maxQuotient - minQuotient + bonus; return res; }

这是我的解决方案:


    import math
    def sol(A, B, K):
    #return ((B-(A-A%K))//K)
    return (math.floor (B/K)- math.ceil (A/K) +1)


sol(6,11,2)


这是我的解决方案:

    function solution(A, B, K) {
        while (B % K > 0) {
            B--;
        }
        while (A % K > 0) {
            A++;
        }

        return (B-A)/K + 1;
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM