Java每次输入一个字符+高精度取整计算(记洛谷P2394题WA+TLE+RE的经历,Java语言描述)
祝大家圣誕節(jié)快樂(lè)
卑微菜雞深夜寫博客~~~55555
其實(shí)這題真的有毒
這題你要是C/C++,雖然語(yǔ)法不是辣么直接,但幾行而已:
#include<bits/stdc++.h>using namespace std;int main(){long double x;scanf("%15Lf",&x);//注意這里特殊寫法printf("%.8Lf",x/23.0);//寫成23也可以return 0; }題意說(shuō)明
P2394題目鏈接
分析
這題簡(jiǎn)直有病,因?yàn)镴ava顯然沒(méi)有C/C++/Python那么方便的輸入輸出體系,而且Java的內(nèi)存開(kāi)銷很大、運(yùn)行時(shí)間很慢……極其不友好~~
但我偏要用Java來(lái)AC掉這個(gè)破題!!!
其實(shí)就是除以23即可,問(wèn)題是這個(gè)數(shù)據(jù)怎么讀。
這個(gè)數(shù)用int啥的承載不了的,如果我們用BigInteger其實(shí)相當(dāng)于就是用String讀的,沒(méi)意思。用String會(huì)爆炸~~
EOF是換行符\n嗎?其實(shí)不一定,但這題表述很差勁,令人費(fèi)解,所以引來(lái)不少誤會(huì)……
(Java給程序員呈現(xiàn)的莫得EOF,所以想通過(guò)’\0’啥的來(lái)judge的肯定不行~~)
另外,運(yùn)算的時(shí)候應(yīng)該用BigDecimal保險(xiǎn)一下~~
問(wèn)題反思
其實(shí)解題過(guò)程中雖然出過(guò)WA、TLE、RE,但是我這次最核心的錯(cuò)誤是RE,這個(gè)RE源于本題題意講解的lj,出自我認(rèn)為終止為\n,實(shí)際上可以基本任意……
第一次提交——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);} }自測(cè):
心態(tài)挺崩的吧,但是還是繼續(xù)吧……
第二次提交——第N次提交
基本情況如下圖:
本來(lái)想利用read()來(lái)做,結(jié)果根本執(zhí)行不下去~~
下面是試圖擴(kuò)增讀入量,顯然失敗~~
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,會(huì)錯(cuò)~~
下面的嘗試也是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);} }有毒般的整了一個(gè)’\n’計(jì)數(shù),搞出了死循環(huá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);} }解決如此令人頭禿的問(wèn)題的思考
首先,主要問(wèn)題是RE,會(huì)錯(cuò)4個(gè)用例,我們先思考什么會(huì)導(dǎo)致RE?
對(duì),Java運(yùn)行時(shí)異常!!
常見(jiàn)的RuntimeException:
- java.lang.NullPointerException 空指針異常;出現(xiàn)原因:調(diào)用了未經(jīng)初始化的對(duì)象或者是不存在的對(duì)象。
- java.lang.ClassNotFoundException 指定的類找不到;出現(xiàn)原因:類的名稱和路徑加載錯(cuò)誤;通常都是程序
試圖通過(guò)字符串來(lái)加載某個(gè)類時(shí)可能引發(fā)異常。 - java.lang.NumberFormatException 字符串轉(zhuǎn)換為數(shù)字異常;出現(xiàn)原因:字符型數(shù)據(jù)中包含非數(shù)字型字符。
- java.lang.IndexOutOfBoundsException 數(shù)組角標(biāo)越界異常,常見(jiàn)于操作數(shù)組對(duì)象時(shí)發(fā)生。
- java.lang.IllegalArgumentException 方法傳遞參數(shù)錯(cuò)誤。
- java.lang.ClassCastException 數(shù)據(jù)類型轉(zhuǎn)換異常
數(shù)組越界?空指針?這些被通常測(cè)試不出問(wèn)題而基本否定。
我們應(yīng)該把目光轉(zhuǎn)向類型轉(zhuǎn)換,思考是否真的是以’\n’結(jié)尾。經(jīng)我測(cè)試,如果不用回車結(jié)尾確實(shí)RE,這樣就要求我們while循環(huán)里的部分條件不再是temp != ‘\n’,而應(yīng)該針對(duì)’0’~‘9’之間+’.’ 這樣11個(gè)字符~~~
于是有了下面的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);} }總結(jié)
以上是生活随笔為你收集整理的Java每次输入一个字符+高精度取整计算(记洛谷P2394题WA+TLE+RE的经历,Java语言描述)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: N进制正反累加判回文数(洛谷P1015题
- 下一篇: 被卡性能的时候要care数据类型(洛谷P