题目描述
晓华所在的工作组正在编写一套高精度科学计算的软件,一些简单的部分如高精度加减法、乘除法早已写完了,现在就剩下晓华所负责的部分:实数的高精度开m次根。
因为一个有理数开根之后可能得到一个无理数,所以这项工作是有较大难度的。现在要做的只是这项工作的第一步:只对自然数进行开整数次根,求出它的一个非负根,并且不考虑结果的小数部分,只要求把结果截断取整即可。
程序需要根据给定的输入,包括需要开根的次数,以及被开根的整数;计算出它的非负根取整后的结果。
输入输出格式
输入格式:
输入文件共有两行,每行都有一个整数,并且输入中没有多余的空格:
第一行有一个正整数m (1 <= m <= 50),表示要开的根次;
第二行有一个整数n (0<=n <= 10^10000),表示被开根的数。
输出格式:
输出文件只有一行,包括一个数,即为开根取整后的结果。
输入输出样例
输入样例#1: 复制
3
1000000000
输出样例#1: 复制
1000
二分来确定上下界;
思路:
求出 l,r;
l^m<=n< r ^m;
import org.omg.CORBA.PUBLIC_MEMBER;
import java.math.*;
import java.time.chrono.*;
import java.util.Calendar;
import java.util.Scanner;
import java.util.function.BiFunction;
public class Main {
public static void main(String[] args) {
Scanner in=new Scanner(System.in);
int m;
BigInteger n;
m=in.nextInt();n=in.nextBigInteger();
BigInteger ll=BigInteger .ZERO;
BigInteger rr=BigInteger .ONE;
while(rr.pow(m).compareTo(n)!=1) {
ll=rr;rr=rr.multiply(BigInteger.valueOf(2));
}
while(ll.add(BigInteger.valueOf(1)).compareTo(rr)==-1) {
BigInteger mid=(ll.add(rr)).divide(BigInteger .valueOf(2));
if(mid.pow(m).compareTo(n)!=1) {
ll=mid;
}else {
rr=mid;
}
}
BigInteger res;
if(rr.pow(m).compareTo(n)!=1)res=rr;
else res=ll;
System.out.println(res);
}
}
import org.omg.CORBA.PUBLIC_MEMBER;
import java.math.*;
import java.time.chrono.*;
import java.util.Calendar;
import java.util.Scanner;
import java.util.function.BiFunction;
public class Main {
public static void main(String[] args) {
Scanner in=new Scanner(System.in);
int m;
BigInteger n;
m=in.nextInt();n=in.nextBigInteger();
BigInteger ll=BigInteger .ZERO;
BigInteger rr=BigInteger .ONE;
while(rr.pow(m).compareTo(n)!=1) {
ll=rr;rr=rr.multiply(BigInteger.valueOf(2));
}
while(ll.add(BigInteger.valueOf(1)).compareTo(rr)==-1) {
BigInteger mid=(ll.add(rr)).divide(BigInteger .valueOf(2));
if(mid.pow(m).compareTo(n)!=1) {
ll=mid;
}else {
rr=mid;
}
}
BigInteger res;
if(rr.pow(m).compareTo(n)!=1)res=rr;
else res=ll;
System.out.println(res);
}
}