这是关于Sherlock和Counting的问题。 https://www.hackerrank.com/challenges/sherlock-and-counting
我使用diffchecker来比较我的代码生成的数千个结果与我使用我的hackos购买的结果。他们是一样的!尽管我的结果与使用hackos购买的结果相同,但我的代码仍然存在错误。
我删除了diffchecker链接,因为它太大并冻结了标签但是我测试了前2000个结果,我的结果与使用hackos购买的结果相同。简单地说,我无法理解为什么 Hackerrank不接受我的代码?您可以尝试输入此代码并注意到您确实获得了与测试用例(使用hackos购买)相同的结果但不知何故不接受吗?
import java.io.*;
import java.util.*;
import java.math.*;
public class Solution {
public static void main(String[] args) {
/* Enter your code here. Read input from STDIN. Print output to STDOUT.
Your class should be named Solution. */
Scanner in = new Scanner(System.in);
int testcases = in.nextInt();
/* Each individual test case */
for(int index = 0; index < testcases; ++index)
{
long N = in.nextLong();
long K = in.nextLong();
/* Notice that we require i < N and i to be a positive integer.
This is impossible if N == 1. Therefore, a simple test solves
a big issue. */
if(N <= 1){
System.out.println(0);
}
/* Test if discriminant is negative. If it is, the number of
integers is N - 1 because every number fits under the graph. */
else if(N*N - 4*N*K < 0)
{
System.out.println(N - 1);
}
/* Notice if the discriminant is zero, then necessarily
N = 4 * K. In an alternate form, the quadratic will be
written as i^2 - Ni + N^2/4, also recognized as (i - N/2)^2.
Therefore, the answer is N - 2. */
else if (N*N - 4*N*K == 0)
{
System.out.println(N - 1);
}
/* Test if discriminant is positive. If it is, the number of
integers depends on the locus of solutions. */
else if(N*N - 4*N*K > 0)
{
long solnOne = (long) (N + Math.sqrt(N*N - 4*N*K))/2;
long solnTwo = (long) (N - Math.sqrt(N*N - 4*N*K))/2;
if(solnOne > solnTwo){
long temp = solnOne;
solnOne = solnTwo;
solnTwo = temp;
}
long LeftBound = (long) solnOne;
long RightBound = (long) solnTwo + 1;
/* Now there may be possibilities such that the left solution
is less than one and/or the right solution is greater than or equal
to the bound. We must account for these possibilities. */
/* Here, both bounds are unacceptable. Therefore, there is no
solution. */
if(LeftBound < 1 && RightBound >= N)
{
System.out.println(0);
}
/* Here, only the right bound is acceptable. */
else if(LeftBound < 1)
{
System.out.println(N - RightBound);
}
/* Here, only the left bound is acceptable. */
else if(RightBound >= N)
{
System.out.println(LeftBound);
}
/* Both bounds are allowed! */
else
{
System.out.println(N - RightBound + LeftBound);
}
}
}
}
}
答案 0 :(得分:0)
试试N=9, K=2
。你的答案是5
有效值为i = [1, 2, 3, 6, 7, 8]
,因此实际答案为6
。
首先,您的solnOne
始终是>=
solnTwo
。翻转它们,if(solnOne > solnTwo)
永远不会成真。
其次,转换为long
会截断值。这就是您solnTwo + 1
的原因,但当solnTwo
完全等于6
时,+ 1
会将其视为有效值。此外,您在除以long
之前转换为2
。糟糕!
相反,不要将 投射到long
:
double solnOne = (N - Math.sqrt(N*N - 4*N*K))/2;
double solnTwo = (N + Math.sqrt(N*N - 4*N*K))/2;
long LeftBound = (long) Math.floor(solnOne);
long RightBound = (long) Math.ceil(solnTwo);
此外,由于HackerRank可能会让您失望,因此性能很重要,所以为了帮助JIT,只计算一次N*N - 4*N*K
并存储在一个变量中。 Math.sqrt(N*N - 4*N*K)
也是如此,因为sqrt()
相对较慢。
对于您自己的测试,您应该将所有内容从if(N <= 1){
开始移动到static long calc(long N, long K)
方法。然后你可以针对它编写单元测试。