POJ-求高精度幂问题,题目编号1001

链接:POJ编号1001的题目

描述:

对数值很大,精度很高的数进行高精度计算是一种十分常见的问题。比如,对国债进行计算就是属于这类问题。

现在你要解决的问题是:对一个实数\large R(0.0 < R < 99.999),要求写程序精确计算 \large R 的 \large n 次方 \large (R^{n}),其中 \large n 是整数并且\large 0 < n \leq 25.

输入:

\large T 输入包括多组 \large R 和 \large n\large R 的值占第1列到第6列,\large n 的值占第8列和第9列。

输出:

对于每组输出,要求输出一行,该行包含精确的 \large R 的 \large n 次方。输出需要去掉前导的0后不要的0。如果输出是整数,不要输出小数点。

样例输入:

95.123 12
0.4321 20
5.1234 15
6.7592  9
98.999 10
1.0100 12

样例输出:

548815620517731830194541.899025343415715973535967221869852721
.00000005148554641076956121994511276767154838481760200726351203835429763013462401
43992025569.928573701266488041146654993318703707511666295476720493953024
29448126.764121021618164430206909037173276672
90429072743629540498.107596019456651774561044010001
1.126825030131969720661201
扫描二维码关注公众号,回复: 2962718 查看本文章

下面的代码仅供参考(Java 语言):源程序中附带注释,说明了解题思路。

/*
 * 解题思路
 * 可以将这个问题分解为几个小问题,分别是以下几点:
 * 1、数据的读入。底数为实数,幂为整数。
 * 因为要从标准输入设备读取数据,所以需要 Scanner 对象。
 * 底数可以考虑 double 类型,但是考虑到高精度的大数运算,所以需要使用 BigDecimal 类型;
 * 幂是整数,使用 int 类型。计算的结果一定是 BigDecimal。
 * 2、读取的数据是一组,个数未知。
 * 因为每次是读取一组数据,不能输入一行数据就输出一个结果。
 * 所以需要将每一行的计算结果保存下来,这里就需要一个 BigDecimal 类型的数组。
 * 因为个数不确定,所以存储结果的数组还需是动态的。
 * 3、结算的结果的格式化。
 * 最后的结果有比较严格的要求。
 * 如果是整数的幂,那么输出的结果必须是整数。
 * 如果是小数的幂,那么结果小数小于0的话,前导0需要去掉。
 * 末尾的无效0必须全部去掉。
 * 所以需要 DecimalFormat 对象。
 */

// 这些类是在需要使用的类。
import java.math.BigDecimal;
import java.text.DecimalFormat;
import java.util.Arrays;
import java.util.Scanner;

// POJ 要求包含 main 方法的类必须叫 Main。
// 类的名称:Main
public class Main
{
	// main 方法
	public static void main(String[] args)
	{
		// 需要从标准输入设备中读取数据,所以需要 Scanner 对象.
		Scanner scanner = new Scanner(System.in);
		
		// 底数需要使用 BigDecimal 类型,因为是高精度的大数计算.
		BigDecimal firstNumber = new BigDecimal(0);
		
		// 幂是整型的.
		int secondNumber = 0;
		
		// 每次读取的是一组输入数据,所以需要将每一行的计算结果进行暂存.
                // 每一行的计算结果为 BigDecimal 类型.
		BigDecimal[] arrayResultBigDecimal = new BigDecimal[0];
		
		// 一个临时数组.用于实现动态数组.
		BigDecimal[] tempArray = null;

		// 终止条件.当没有输入时结束循环.
		while(scanner.hasNext())
		{
			// 以下3行代码,实现动态数组.这只是表象的动态数组,其本质不是动态数组.                     
                        // 但是能实现相同的功能.
			tempArray = new BigDecimal[arrayResultBigDecimal.length + 1];
			tempArray = Arrays.copyOf(arrayResultBigDecimal, tempArray.length);
			arrayResultBigDecimal = tempArray;
			
			// 首先从标准输入设备中读取某一行中的底数.
			firstNumber = scanner.nextBigDecimal();
			
			// 然后从标准输入设备中读取某一行中的幂.
			secondNumber = scanner.nextInt();
			
			// 进行底数的幂次运算.结果也为 BigDecimal 类型.
			BigDecimal mutiplyResult = firstNumber.pow(secondNumber);
			
			// 将一行的计算结果暂存到数组中,等待所有的运算结束后输出.
			arrayResultBigDecimal[arrayResultBigDecimal.length-1] = mutiplyResult;
		}
		
		// 关闭 Scanner 对象资源.
		scanner.close();
		
		
		// 调整 BigDecimal 对象的格式,需要用到 DecimalFormat 对象.
		DecimalFormat decimalFormat = new DecimalFormat();
		
		// 设置最大的小数的位数.
		decimalFormat.setMaximumFractionDigits(340);
		
		// 设置组显示分隔符状态:不显示.
		decimalFormat.setGroupingUsed(false);
		
		
		// 下面依次调整每一行的计算结果的格式.
		for(int i=0;i<arrayResultBigDecimal.length;++i)
		{
			// 这是初步调整的运算结果,还没有去掉前导0,后无效0.
			String string = decimalFormat.format(arrayResultBigDecimal[i]);
			
			// 使用 StringBuilder 对象,对字符串进行修改.
                        // 因为 Sting 对象不可修改.
			StringBuilder stringBuilder = new StringBuilder(string);
			
			// 如果是小数,且小于0的话.
			if(arrayResultBigDecimal[i].compareTo(new BigDecimal(1)) < 0)
			{
				// 首先去掉前导0.
				stringBuilder.deleteCharAt(0);
				
				// 逐个去掉小数末尾无效的0.
				while(true)
				{
					if(stringBuilder.charAt(stringBuilder.length()-1) == '0')
					{
						stringBuilder.deleteCharAt(stringBuilder.length()-1);
					}
					else
					{
						break;
					}
				}
				
			}
			
			// 将调整好的运算结果输出.
			System.out.println(stringBuilder);
		}
	}
}

Over!

猜你喜欢

转载自blog.csdn.net/PursueLuo/article/details/82191458