2016-06-04 3 views
1

c'est en ce qui concerne le problème Sherlock et comptage. J'ai utilisé diffchecker pour comparer des milliers de résultats que mon code a produits avec les résultats que j'ai achetés en utilisant mes hackos. Ce sont les mêmes! Mon code revient défectueux malgré mes résultats étant les mêmes que les résultats achetés en utilisant les hackos. J'ai supprimé le lien diffchecker car il est trop grand et gèle la tabulation mais j'ai testé les 2000 premiers résultats et mes résultats sont les mêmes que ceux obtenus avec les hackos. Tout simplement, je ne peux pas comprendre pourquoi Hackerrank n'accepte pas mon code? Vous pouvez essayer d'entrer ce code et de remarquer que vous obtenez en effet les mêmes résultats que les cas de test (acheté en utilisant les hackos) mais en quelque sorte il ne l'accepte pas?Sherlock et le comptage ne pas être accepté par HackerRank

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); 
       } 
      } 
     } 

    } 
} 

Répondre

0

Essayez N=9, K=2. Votre réponse est 5.
Les valeurs valides sont i = [1, 2, 3, 6, 7, 8], donc la vraie réponse est 6. D'abord, votre solnOne est toujours >=solnTwo. Retournez-les et votre if(solnOne > solnTwo) ne sera jamais vrai. Ensuite, la conversion en longtronque les valeurs. C'est pourquoi vous faites solnTwo + 1, mais quand solnTwo est exactement égal à 6, le + 1 manquera cela comme valeur valide. En outre, vous avez casté en longavant en divisant par 2. Oops!

Au lieu de cela, ne pas fonte-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); 

En outre, depuis HackerRank peut vous expirer, les questions de performance, pour ainsi aider JIT, calculer N*N - 4*N*K une seule fois et stocker dans une variable. Idem pour Math.sqrt(N*N - 4*N*K), puisque sqrt() est relativement lent.

Pour vos propres tests, vous devez déplacer tout, à partir de if(N <= 1){, dans une méthode static long calc(long N, long K). Ensuite, vous pourriez écrire des tests unitaires contre cela.

+0

Vous avez raison. Pour le 'rightBound' je n'ai pas vérifié qu'il pouvait effectivement se croiser avec l'axe des x. –

+0

J'ai fait tout ce que vous avez suggéré et maintenant j'en ai 6 pour ma réponse. Cependant, mes cas de test échouent toujours. Est-ce que je poste un nouvel extrait dans ce commentaire, puis-je mettre à jour le contenu du code de l'OP ou remplacer le contenu du code OP? –

+0

@MathApprentice * Vous * êtes l'OP (Original Poster) de la question. Je suis l'OP de * cette * réponse. Donc vous voyez, votre commentaire est un peu bizarre. ;-) Si ma réponse vous a aidé, vous devez cliquer sur la flèche vers le haut (info-bulle: Cette réponse est utile). Si ma réponse résout votre problème, vous devez simplement l'accepter en cliquant sur la coche, montrant ainsi aux autres que votre question a été répondue à votre satisfaction. Si vous avez une clarification à la question, éditez-la. Si vous avez une question différente, créez-en une nouvelle. Si vous ne pensez pas que cette question va profiter aux autres, supprimez-la. – Andreas