题解 P1517 【高精求小数幂】

· · 题解

这里没有Java的题解,补充一下挺好的。

因为Java在acm-icpc中可以使用,而且天然支持BigDecimal进行高精度小数运算,所以学习一下BigDecimal还是有必要的。

第一次做的时候错了很多次,因为输出格式的原因,BigDecimal默认的toSting()方法在某些情况会变成科学计数法,但是这里要求是平凡的计数法,所以要用BigDecimal的toPlainString()方法转化成准确的字符串。

要用toPlainString()! 要用toPlainString()! 要用toPlainString()!

后面的操作都比较常规,大家都可以看看注释明白。

题外话:BigDecimal的除法和BigInteger略有不同,因为BigDecimal的除法理论上是无限精度的,要是除不尽就必须要截断末尾保留精度。但是这里只用朴素的乘法就没有这个问题。

import java.math.BigDecimal;
import java.util.Scanner;

public class Main {
    public static void main(String args[]) {
        Scanner sc=new Scanner(System.in);
        while(sc.hasNext()) {
            BigDecimal x=sc.nextBigDecimal();
            int n=sc.nextInt();

            BigDecimal ans=BigDecimal.ONE;
            for(int i=0;i<n;i++) {
                ans=ans.multiply(x);
                //BigDecimal的乘法需要调用multiply()方法,乘以一个BigDecimal对象,返回一个BigDecimal对象
            }

            String s=ans.toPlainString();
            //在这里要使用toPlainString()方法,默认的toString()方法在某些情况是科学计数法,错了很多次才知道

            /*
             * 例如样例:
             * 0.000001 5 
            */

            int len=s.length();
            int leadzero=-1;
            boolean metdot=false;
            for(int i=0;i<len;i++) {
                if(leadzero==-1&&s.charAt(i)!='0') {
                    leadzero=i;
                    //把整数部分的0去掉
                }
                if(s.charAt(i)=='.') {
                    metdot=true;
                    //遇到了小数点,说明是小数
                    break;
                }
            }

            if(metdot==true) {
                s=s.substring(leadzero);
                //遇到了小数点,说明是小数
                len=s.length();
                //重新计算s的长度,因为前面可能截断了整数部分的0
                int releadzero=-1;
                for(int i=len-1;i>=0;i--) {
                    if(s.charAt(i)!='0') {
                        releadzero=i+1;
                        //遇到第一个非零位置,其后的无效0截断
                        if(s.charAt(i)=='.') {
                            releadzero=i;
                            //遇到第一个非零位置是小数点,连小数点也截断
                        }
                        break;
                    }
                }
                s=s.substring(0,releadzero);
            }
            else {
                //没有遇到小数点,是整数,不可能有无效0
                ;
            }

            System.out.println(s);
        }
        sc.close();
    }
}