Java每次输入一个字符+高精度取整计算(记洛谷P2394题WA+TLE+RE的经历,Java语言描述)
祝大家圣誕節快樂
卑微菜雞深夜寫博客~~~55555
其實這題真的有毒
這題你要是C/C++,雖然語法不是辣么直接,但幾行而已:
#include<bits/stdc++.h>using namespace std;int main(){long double x;scanf("%15Lf",&x);//注意這里特殊寫法printf("%.8Lf",x/23.0);//寫成23也可以return 0; }題意說明
P2394題目鏈接
分析
這題簡直有病,因為Java顯然沒有C/C++/Python那么方便的輸入輸出體系,而且Java的內存開銷很大、運行時間很慢……極其不友好~~
但我偏要用Java來AC掉這個破題!!!
其實就是除以23即可,問題是這個數據怎么讀。
這個數用int啥的承載不了的,如果我們用BigInteger其實相當于就是用String讀的,沒意思。用String會爆炸~~
EOF是換行符\n嗎?其實不一定,但這題表述很差勁,令人費解,所以引來不少誤會……
(Java給程序員呈現的莫得EOF,所以想通過’\0’啥的來judge的肯定不行~~)
另外,運算的時候應該用BigDecimal保險一下~~
問題反思
其實解題過程中雖然出過WA、TLE、RE,但是我這次最核心的錯誤是RE,這個RE源于本題題意講解的lj,出自我認為終止為\n,實際上可以基本任意……
第一次提交——TLE+RE
import java.math.BigDecimal; import java.util.Scanner;public class Main {public static void main(String[] args) {Scanner scanner = new Scanner(System.in);BigDecimal number = new BigDecimal(scanner.nextLine());scanner.close();number = number.divide(new BigDecimal("23"));double result = number.doubleValue();System.out.printf("%.8f", result);} }自測:
心態挺崩的吧,但是還是繼續吧……
第二次提交——第N次提交
基本情況如下圖:
本來想利用read()來做,結果根本執行不下去~~
下面是試圖擴增讀入量,顯然失敗~~
import java.io.*; import java.math.BigDecimal; import java.math.RoundingMode; import java.util.ArrayList; import java.util.List;public class Main {public static void main(String[] args) throws IOException {BufferedReader jin = new BufferedReader(new InputStreamReader(System.in));int counter = 0, i = 0;List<Character> list = new ArrayList<>(16);char temp = (char)System.in.read();while(temp != '\n' && counter < 32) {list.add(temp);temp = (char)System.in.read();counter++;}jin.close();char[] array = new char[list.size()];for (char c : list) {array[i] = c;i++;}BigDecimal number = new BigDecimal(array);number = number.divide(new BigDecimal("23"), 8, RoundingMode.HALF_UP);double result = number.doubleValue();System.out.printf("%.8f", result);} }下面的一次嘗試甚至還WA了:
這么弄不行誒,畢竟直接嘗試打印BigDecimal,會錯~~
下面的嘗試也是RE依舊:
import java.io.*; import java.math.BigDecimal; import java.math.RoundingMode; import java.util.ArrayList; import java.util.List;public class Main {public static void main(String[] args) throws IOException {BufferedReader jin = new BufferedReader(new InputStreamReader(System.in));int counter = 0, i = 0;List<Character> list = new ArrayList<>(16);char temp = (char)System.in.read();while(temp != '\n' && temp != ' '&& counter < 16) {list.add(temp);temp = (char)System.in.read();counter++;}jin.close();char[] array = new char[list.size()];for (char c : list) {array[i] = c;i++;}BigDecimal number = new BigDecimal(array);number = number.divide(new BigDecimal("23"), 8, RoundingMode.HALF_UP);double result = number.doubleValue();System.out.printf("%.8f", result);} }然后嘗試加上’\0’,再次印證不行:
import java.io.*; import java.math.BigDecimal; import java.math.RoundingMode; import java.util.ArrayList; import java.util.List;public class Main {public static void main(String[] args) throws IOException {BufferedReader jin = new BufferedReader(new InputStreamReader(System.in));int counter = 0, i = 0;List<Character> list = new ArrayList<>(16);char temp = (char)System.in.read();while(temp != '\n' && temp != '\0'&& counter < 16) {list.add(temp);temp = (char)System.in.read();counter++;}jin.close();char[] array = new char[list.size()];for (char c : list) {array[i] = c;i++;}BigDecimal number = new BigDecimal(array);number = number.divide(new BigDecimal("23"), 8, RoundingMode.HALF_UP);double result = number.doubleValue();System.out.printf("%.8f", result);} }有毒般的整了一個’\n’計數,搞出了死循環阻塞~~
import java.io.*; import java.math.BigDecimal; import java.math.RoundingMode; import java.util.ArrayList; import java.util.List;public class Main {public static void main(String[] args) throws IOException {BufferedReader jin = new BufferedReader(new InputStreamReader(System.in));int counter = 0, i = 0;List<Character> list = new ArrayList<>(16);char temp = (char)System.in.read();while(temp != '\n' && counter < 16) {list.add(temp);temp = (char)System.in.read();counter++;}while (temp == '\n') {temp = (char)System.in.read();}jin.close();char[] array = new char[list.size()];for (char c : list) {array[i] = c;i++;}BigDecimal number = new BigDecimal(array);number = number.divide(new BigDecimal("23"), 8, RoundingMode.HALF_UP);double result = number.doubleValue();System.out.printf("%.8f", result);} }解決如此令人頭禿的問題的思考
首先,主要問題是RE,會錯4個用例,我們先思考什么會導致RE?
對,Java運行時異常!!
常見的RuntimeException:
- java.lang.NullPointerException 空指針異常;出現原因:調用了未經初始化的對象或者是不存在的對象。
- java.lang.ClassNotFoundException 指定的類找不到;出現原因:類的名稱和路徑加載錯誤;通常都是程序
試圖通過字符串來加載某個類時可能引發異常。 - java.lang.NumberFormatException 字符串轉換為數字異常;出現原因:字符型數據中包含非數字型字符。
- java.lang.IndexOutOfBoundsException 數組角標越界異常,常見于操作數組對象時發生。
- java.lang.IllegalArgumentException 方法傳遞參數錯誤。
- java.lang.ClassCastException 數據類型轉換異常
數組越界?空指針?這些被通常測試不出問題而基本否定。
我們應該把目光轉向類型轉換,思考是否真的是以’\n’結尾。經我測試,如果不用回車結尾確實RE,這樣就要求我們while循環里的部分條件不再是temp != ‘\n’,而應該針對’0’~‘9’之間+’.’ 這樣11個字符~~~
于是有了下面的AC代碼:
AC代碼
import java.io.*; import java.math.BigDecimal; import java.math.RoundingMode; import java.util.ArrayList; import java.util.List;public class Main {public static void main(String[] args) throws IOException {BufferedReader jin = new BufferedReader(new InputStreamReader(System.in));int counter = 0, i = 0;List<Character> list = new ArrayList<>(16);char temp = (char)System.in.read();while((temp <= '9' && temp >= '0' || temp == '.') && counter < 20) {list.add(temp);temp = (char)System.in.read();counter++;}jin.close();char[] array = new char[list.size()];for (char c : list) {array[i] = c;i++;}BigDecimal number = new BigDecimal(array);number = number.divide(new BigDecimal("23"), 8, RoundingMode.HALF_UP);double result = number.doubleValue();System.out.printf("%.8f", result);} }總結
以上是生活随笔為你收集整理的Java每次输入一个字符+高精度取整计算(记洛谷P2394题WA+TLE+RE的经历,Java语言描述)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: N进制正反累加判回文数(洛谷P1015题
- 下一篇: 被卡性能的时候要care数据类型(洛谷P