我在SiteFights中遇到了一个问题,我用两个循环解决了这个问题。在看其他答案的时候,我找到一个解决它没有循环,它让我张开嘴。编码器应用了Math.min / max,虽然我明白代码的作用,但我不明白为什么它有效。
我很乐意学习,因为heck,Math.max / min肯定会打败我的循环中的字节。
Given integers n, l and r, find the number of ways to represent n as a sum
of two integers A and B such that l ≤ A ≤ B ≤ r.
Example
For n = 6, l = 2 and r = 4, the output should be
countSumOfTwoRepresentations2(n, l, r) = 2.
There are just two ways to write 6 as A + B, where 2 ≤ A ≤ B ≤ 4: 6 = 2 + 4 and 6 = 3 + 3.
Input/Output
[time limit] 4000ms (js)
[input] integer n
A positive integer.
Constraints:
5 ≤ n ≤ 109.
[input] integer l
A positive integer.
Constraints:
1 ≤ l ≤ r.
[input] integer r
A positive integer.
Constraints:
l ≤ r ≤ 109,
r - l ≤ 106.
编码员的惊人答案:
function countSumOfTwoRepresentations2(n, l, r) {
return Math.max(Math.min(Math.floor(n / 2) - l, r - Math.ceil(n / 2)) + 1, 0);
}
我的废话比较:
function countSumOfTwoRepresentations2(n, l, r) {
var representations = 0;
//Only travel the loop until n/2 , because l+r will never equal n
// if l or r > n/2
var limit = Math.floor(n/2);
for(var i=l; i<=r && i<=limit; ++i){
for(var j=i;j<=r;++j){
if(i+j == n){
++representations;
break;
}
}
}
return representations;
}
答案 0 :(得分:3)
给定整数
n
,l
和r
,找出将n表示为两个整数A
和B
的总和的方法的数量,以便l ≤ A ≤ B ≤ r
。
首先,考虑如果n
是偶数并让x = n/2
,我们至少有一个解决方案(x + x
),当且仅当l ≤ x ≤ r
时。如果x
不在该范围内,那么就没有解决方案,因为x < l
和l + l > n
或r < x
和r + r < n
。
可以推广到偶数或奇数n
:如果且仅限于l ≤ floor(x) ≤ ceil(x) ≤ r
,则有一个解决方案。如果我们允许A = floor(x)
和B = ceil(x)
,则该解决方案为A + B
。通过在每个方向上从该点开始沿着数字线迈出一步,可以找到所有其他解决方案。 (A - 1) + (B + 1) = A + B = n
,因此只要(A - 1) + (B + 1)
没有越过(A - 1)
边界且l
没有越过(B + 1)
,r
就是一个解决方案{1}}边界。所以,如果你想要一个只有一个循环的解决方案,你可以这样做:
function countSumOfTwoRepresentations2(n, l, r) {
var x = n/2;
var A = Math.floor( x );
var B = Math.ceil( x );
for ( var count = 0; l <= A && B <= r; count++) {
A--;
B++;
}
return count;
}
但该循环重复多少次?好吧,它会迭代,直到其中一个停止条件发生:
A
小于l
B
变得大于r
如果1.
首先发生,那么它会迭代Math.floor( x ) - l + 1
次,而如果先发生2.
,它会迭代r - Math.ceil( x ) + 1
(如果两个条件都发生在同一次迭代中,那么{ {1}})。
只要有一个解决方案,循环就会迭代较小的Math.floor( x ) - l === r - Math.ceil( x )
或Math.floor( x ) - l + 1
次,这就是编码器得到答案r - Math.ceil( x ) + 1
的地方(在替换{{1}之后) }返回Math.min(Math.floor(n / 2) - l, r - Math.ceil(n / 2)) + 1
并将x
拉出每个字词并在之后添加。
如果没有解决方案,n/2
,该公式会给出否定结果,但应该提供+ 1
,这就是他添加EG. n = 10, l = 20, r = 20
的原因。
为清楚起见,编码器的解决方案可以写成(仍然没有循环):
0