2012-04-03 47 views
-4

我試圖解決我的codechef得到運行時錯誤NZEC問題http://www.codechef.com/APRIL12/problems/DUMPLING/獲取NZEC在Java代碼中

。我在互聯網上搜索,但沒有設法讓我的代碼成功。

這是我的代碼:

import java.io.BufferedReader; 
import java.io.IOException; 
import java.io.InputStreamReader; 
import java.math.BigInteger; 

public class Main { 

    public BigInteger gcd(BigInteger a,BigInteger b){ 
     if(b.compareTo(BigInteger.valueOf(0)) == 0) 
      return a; 
     return gcd(b,a.mod(b)); 
    } 

    public static void main(String[] args) { 
     BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); 
     String str; 
     int t = 1; 
     Main obj = new Main(); 
     try{ 
      str = br.readLine(); 
      t = Integer.parseInt(str); 
     } 
     catch(IOException e){ 
      System.out.println("error"); 
     } 

     for(int w = 0; w < t; w++){ 
      BigInteger a = BigInteger.valueOf(1); 
      BigInteger b = BigInteger.valueOf(1); 
      BigInteger c = BigInteger.valueOf(1); 
      BigInteger d = BigInteger.valueOf(1); 
      BigInteger k = BigInteger.valueOf(1); 
      try{ 
       str = br.readLine(); 
       String s[] = str.split(" "); 
       a = new BigInteger(s[0]); 
       b = new BigInteger(s[1]); 
       c = new BigInteger(s[2]); 
       d = new BigInteger(s[3]); 
       k = new BigInteger(s[4]); 
      } 
      catch(IOException e){ 
       System.out.println("error"); 
      } 

      BigInteger g1,g2,num; 
      if(a.compareTo(b) < 0){ 
       num = a; 
       a = b; 
       b = num; 
      } 

      if(c.compareTo(d) < 0){ 
       num = c; 
       c = d; 
       d = num; 
      } 

      g1 = obj.gcd(a,b); 
      g2 = obj.gcd(c,d); 

      if(g1.compareTo(g2) < 0){ 
       num = g1; 
       g1 = g2; 
       g2 = num; 
      } 
      BigInteger g3 = obj.gcd(g1,g2); 

      BigInteger l = g1.divide(g3); 
      l = l.multiply(g2); 

      BigInteger res = k.divide(l); 
      BigInteger fin = res.multiply(BigInteger.valueOf(2)); 
      fin = fin.add(BigInteger.valueOf(1)); 
      System.out.println(fin); 
     } 
    } 

} 

誰能請告訴我,我在哪裏做錯了嗎?

+2

我不明白這一行的意思:'我得到運行時錯誤NZEC on codechef'你是否得到一個Java'Exception'?如果是這樣你可以發佈完整的堆棧跟蹤? – ulmangt 2012-04-03 16:35:06

+1

我們應該猜測「NZEC」代表什麼,它出現在哪條線上,輸入的是什麼?如果你不幫助我們幫助你,你真的期望什麼? – 2012-04-03 16:35:25

+0

我在netbeans上運行我的系統上的代碼,它工作正常,但是當我在codechef上提交代碼時,它向我展示了一個運行時錯誤。並且他們不給我們代碼顯示錯誤的行。所以,即使我不爲什麼它顯示運行時錯誤? – 2012-04-03 16:39:24

回答

11

除非不太可能的場景,用於獲取與程序,我看到的是

  • 除數爲零非零退出代碼,但如果輸入符合規範,不能發生的唯一可能性
  • 意想不到的輸入格式導致一個NumberFormatException

所以我正在關閉後者的假設。一個簡單的方法來檢查將與catch(Exception e)更換兩個catch(IOException e),如果輸入的確不是你所期望的格式,你會得到一個「錯誤答案」,那麼(但改變後得到一個WA並不能證明的假設正確)。

第一行上的任何其他空格都會導致在Integer.parseInt(str)中。在以後的任何行額外的空格會導致String[]創建通過str.split(" ")有超過五種元素,如果有這樣的出現在該行的第五號之前,該計劃將嘗試創建BigInteger.valueOf(""),這又導致NumberFormatException。所以我會推薦一個更強大的輸入法,例如java.util.Scanner,它可以處理額外的空白而沒有問題。這裏使用的方法是測試用例的數量爲nextInt(),其餘爲nextLong()

Scanner scn = new Scanner(System.in); 
int t = scn.nextInt(); 
for(int w = 0; w < t; w++){ 
    BigInteger a = BigInteger.valueOf(scn.nextLong()); 
    BigInteger b = BigInteger.valueOf(scn.nextLong()); 
    BigInteger c = BigInteger.valueOf(scn.nextLong()); 
    BigInteger d = BigInteger.valueOf(scn.nextLong()); 
    BigInteger k = BigInteger.valueOf(scn.nextLong()); 

    BigInteger g1,g2,num; 
    ... 

如果變化導致的接受,對於NZEC原因很可能意外輸入格式。


你問

誰能請告訴我,我在哪裏做錯了嗎?

所以我會指出一些不嚴格不正確的事情,但不好的做法/毫無意義。

public BigInteger gcd(BigInteger a,BigInteger b){ 
    if(b.compareTo(BigInteger.valueOf(0)) == 0) 
     return a; 
    return gcd(b,a.mod(b)); 
} 

該方法應該是static。它不涉及任何狀態,所以不得不創建一個對象來調用它是不好的。

還有一點,不相關的像那些可能出現的問題,小的數字,但如果你處理大量相關的,是你來了遞歸。 Java通常(如果曾經)不執行尾部調用優化,並且調用堆棧通常只能處理幾千個調用,因此您有遞歸實現的風險StackOverflowError。 (但由於呼叫深度是歐幾里得算法的對數,因此只涉及較大的數字。)

catch(IOException e){ 
    System.out.println("error"); 
} 

捕獲一個異常只是爲了向標準輸出打印「錯誤」是不好的。如果你不能做一些更有意義的事情來處理它,不要抓住它。

for(int w = 0; w < t; w++){ 
    BigInteger a = BigInteger.valueOf(1); 
    BigInteger b = BigInteger.valueOf(1); 
    BigInteger c = BigInteger.valueOf(1); 
    BigInteger d = BigInteger.valueOf(1); 
    BigInteger k = BigInteger.valueOf(1); 

分配虛擬價值的變量是沒有意義的,他們將立即着手其實際價值(或者如果失敗的程序應該死)。

try{ 
     str = br.readLine(); 
     String s[] = str.split(" "); 
     a = new BigInteger(s[0]); 
     b = new BigInteger(s[1]); 
     c = new BigInteger(s[2]); 
     d = new BigInteger(s[3]); 
     k = new BigInteger(s[4]); 
    } 
    catch(IOException e){ 
     System.out.println("error"); 
    } 

再次無意義的catch

if(a.compareTo(b) < 0){ 
     num = a; 
     a = b; 
     b = num; 
    } 

    if(c.compareTo(d) < 0){ 
     num = c; 
     c = d; 
     d = num; 
    } 

我懷疑你交換,以避免mod操作,其中,股息比除數小。有些地方這種微觀優化很重要,但這不是其中之一。如果你有理由關心這樣的小事情,那麼還有很多事情要做。例如,可以使用long(有一個地方需要調整算法以避免可能的溢出)解決手頭上的問題,並且該基元類型的算術運算速度快得多,可以使您從交換中獲得的小增益這裏。

+4

加入+1的努力 - 即使你的答案沒有解決OP的問題(這將是他的錯,不是你的錯),你應該得到它。 – 2012-04-04 08:33:04

0

嘗試使用BufferedReader而不是Scanner類,而不是使用try-catch使用throws NumberFormatException並引發IOException。如果你使用try-catch,這很有用,你可能會得到一個錯誤的答案。