51Nod-1166大数开平方(java版本)

题目

https://vjudge.net/problem/51Nod-1166

思路

用更快的牛顿迭代法。把问题转化为求x^2 -n=0的根,假设解为x0,当前解为x 且 x^2 - n>0,在(x,x^2 - n)处作切线,与x轴交点横坐标为新的x,然后迭代即可,比二分法快

牛顿迭代法(Newton’s method)又称为牛顿-拉夫逊(拉弗森)方法(Newton-Raphson method),它是牛顿在17世纪提出的一种在实数域和复数域上近似求解方程的方法。公式为:(x+a/x)/2

这种方法可以很有效地求出根号a的近似值:例如,我想求根号2等于多少。使用牛顿迭代法后这个值很快就趋近于根号2了:
(4 + 2 / 4) / 2 = 2.25
(2.25 + 2 / 2.25) / 2 = 1.56944…
(1.56944… + 2/1.56944…) / 2 = 1.42189…
(1.42189… + 2/1.42189…) / 2 = 1.41423…

代码

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.math.BigInteger;
import java.util.StringTokenizer;

public class Main {

	/**
	 * @param args
	 * @throws Exception
	 */
	public static void main(String[] args) throws Exception {
		String a = _07Reader.next();
		BigInteger N = new BigInteger(a);
		//下面的if语句不晓得干什么的,不带上会超时
		//如果输入的是偶数位的数,例如16
		if (N.toString().length() % 2 == 0) {
			//截取这两位数
			a = a.substring(0, N.toString().length()/2 + 1);
		}else {
			a = a.substring(0, (1+N.toString().length())/2);
		}
		BigInteger x = new BigInteger(a);
		BigInteger two = new BigInteger("2");
		//考虑输入是1的情况
		if (a == "1") {
			System.out.println(1);
		}else {
			//N - x^2 < 0的条件
			while (N.compareTo(x.multiply(x)) < 0) {
				//导入公式(x+a/x)/2
				x = x.add(N.divide(x)).divide(two);
			}
			System.out.println(x);
		}
	}

}

class _07Reader {
	static BufferedReader br = new BufferedReader(new InputStreamReader(
			System.in));
	static StringTokenizer tokenizer = new StringTokenizer("");

	static String next() throws Exception {
		while (!tokenizer.hasMoreTokens()) {
			tokenizer = new StringTokenizer(br.readLine());
		}
		return tokenizer.nextToken();
	}

	static String nextLine() throws Exception {
		return br.readLine();
	}

	static int nextInt() throws Exception {
		return Integer.parseInt(next());
	}

}

拓展

这个是求BigDecimal平方根的方法,遇到这样的题再说吧,先放着…
JAVA BigDecimal使用牛顿迭代法计算平方根

发布了60 篇原创文章 · 获赞 4 · 访问量 1250

猜你喜欢

转载自blog.csdn.net/qq_43966129/article/details/105369089
今日推荐