首页 > 试题广场 >

开根号

[编程题]开根号
  • 热度指数:2566 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 32M,其他语言64M
  • 算法知识视频讲解

在没有任何数学库函数的情况下,求一个数 m n 次方的结果。


输入描述:

每组输入只有1行,包括有一个正实数m和一个正整数n,其中1 <= n <= 32, 1<=m<=



输出描述:
输出只有一行,打印m开n次方的结果,小数点后面保留12位。
示例1

输入

2 10

输出

1.071773462536
import java.text.DecimalFormat;
import java.util.Scanner;
public class Main{
    public static void main(String[] args){
        Scanner s=new Scanner(System.in);
        double m=s.nextDouble();
        double n=s.nextDouble();
        double res=m;
            res=Math.pow(res,1/n);
        DecimalFormat df=new DecimalFormat("#.000000000000");
        System.out.print(df.format(res));
    }
}


发表于 2020-02-25 13:42:12 回复(1)
#include<stdio.h>

int main()
{
double m,n;
scanf("%lf%lf",&m,&n);
double l,u,mid;
l = 1;
u = m;
double eps = 1e-13;
do
{
mid = (l+u)/2;
double tmp = 1;
for(int i = n; i>0; i--)
{
tmp = tmp*mid;
}
if (tmp < m)
l = mid;
else
u = mid;
}
while(u-l>eps);
printf("%.12f",l);
}
编辑于 2020-07-07 09:38:33 回复(0)
这道题一开始就想到数值计算牛顿迭代法
发表于 2020-02-21 16:28:49 回复(0)
二分答案求开根号
注意eps
#include <bits/stdc++.h>
using namespace std;
const double eps=1e-16;
long double n,m;
int main(){
    scanf("%Lf%Lf",&m,&n);
    long double l=0.0,r=2.0;
    while(fabs(r-l)>=eps){
        long double mid=(l+r)/2;
        long double tmp=pow(mid,n);
        if(tmp>m){
            r=mid;
        }else{
            l=mid;
        }
    }
    printf("%.12Lf\n",l);
    return 0;
}


发表于 2020-01-24 23:44:52 回复(4)
#include <iostream>
#include <iomanip>
using namespace std;
const double err = 1.0e-12;
 
long int pow(int n) {
    //主要进行m的取值是不是在范围内(2^n≥m≥1)
    if(n == 1) return 2;
    else{
        return 2 * pow(n - 1);
    }
}
 
double pow_h(int n, double ori) {
    //主要是用来求解 x*x*x*x*...*x 的值,通过这个与输入m比较是否在误差范围内
    double res = 1.0;
    //可以直接递归,都可以(看自己选择)
    for(int i = 0; i < n; i++) {
        res = res*ori;
    }
    return res;
}
double pre_h(double m,  int n, double res, double h, double l) {
 
    //看着res不舒服,换个名称
    double x = res;
    //得到 x*x*x*x....*x的值
    double result = pow_h(n, x);
    double high,low;
    if(result > m) {
        
        if((result - m) <= err) return x;
        else{
             //进来说明给出的初值x过大,那么就在 l~x之间选取中值(二分的意思)
            high = x;
            low = l;
            x = (x + l) / 2.0;
            return pre_h(m, n, x,high,low);
        }
    }
    else{
         
        if((m - result) <= err) return x;
        else{
            //进来说明给出的初值x过大,那么就在 x~h之间选取中值(二分的意思)
            low = x;
            high = h;
            x = (x + h) / 2.0;
            return pre_h(m, n, x,high,low);
        }
    }
}
 
int main() {
    int n;
    double m;
    double res;
    //scanf_s("%d %d", &m, &n);
    cin >> m >> n;
    if(n > 32 || n < 1) {
        cout << "input error"<< endl;
        return 0;
    }
    if(m < 1 || m > pow(n)) {
        cout << "m : input error"<< endl;
        return 0;
    }
    res = pre_h(m, n, 1.0,m,1.0);  //第一个1.0意思就是选取的初值x,第二个1.0就是区间的最小值
    cout << setiosflags(ios::fixed)<< setprecision(12) << res << endl;
    return 0;
}
发表于 2020-06-17 09:58:40 回复(0)
#include <bits/stdc++.h>
using namespace std;
int main(){
    int n;
    double m;
    cin>>m>>n;
    //浮点数二分模板
    double l = 0;
    double r = m;
    while (r-l>1e-14){
        double mid = (l+r)/2;
        if(pow(mid,n)>=m)
            r = mid;
        else
            l = mid;
    }
    printf("%.12lf\n",l);
    return 0;
}


发表于 2020-02-21 23:24:01 回复(1)
//注意审题:不用任何数学库函数,所以我们只用加减乘除
#include <iostream>
using namespace std;
//二分搜索求开n次方
double epr = 10E-14;
double Mysqrt(double m, int n)
{
    double left = 0;
    double right = m;
    double mid = left + (right - left) / 2;
    double last;//保存上一次运算的结果
    double temp;
    do {
        //m除以mid n-1次
        temp = m;
        for (int i = 0; i<n-1; i++)
            temp = temp / mid;
        //二分
        if (mid>temp)
            right = mid;
        else
            left = mid;
        //记录、更新
        last = mid;
        mid = left + (right - left) / 2;
    } while (mid - last>epr ||mid - last<-epr);
    return mid;
}
int main()
{
    double m;
    int n;
    while (cin >> m >> n)
    {
        cout.precision(13);
        cout << Mysqrt(m, n);
    }
}

发表于 2020-02-08 16:08:15 回复(4)
while True:
    try:
        m, n = list(map(int, input().split()))#是m取值问题,int就是6/10通过;float就全部通过
        m=float(m)
        n = int(n)
        begin=0.0
        end=m*1.0
        midpre = 0
        #x=(end+begin)/2#两个数之间

        while True:
            x=(end+begin)/2
            sum = 1.0
            for i in range(n):
                sum=sum*x
                
            if sum>m*1.0:
                end=x
            elif sum<m*1.0:
                begin=x
            if abs(sum - m) < 1e-12:
                #print(x)
                print('%.12f' % x)
                break
            
    except:
        break

发表于 2022-08-23 16:08:18 回复(1)
C++  牛顿迭代 因为最后结果在[1,2]之间,所以这里设初值为1
#include <iostream>
using namespace std;
//x的y次方
double power(double x,int y){
    double ans=1;
    for(int i=0;i<y;i++){
        ans*=x;
    }
    return ans;
}
//绝对值
long double myabs(long double a){
    return a>0?a:-a;
}
//开n次根号
long double nsqrt(long double m,int n){
    long double ans=1;
    while(myabs(power(ans,n)-m)>=1e-12){
        ans=ans-(double)(power(ans,n)-m)/(double)(n*power(ans,n-1));
    }
    return ans;
}

int main(int argc,char* argv[]){
    long double m,n;
    cin>>m>>n;
    cout.precision(13);
    cout<<nsqrt(m, n)<<endl;
    return 0;
}

发表于 2021-07-15 22:14:09 回复(0)
#include <bits/stdc++.h>
using namespace std;
 
int main(int argc, char *argv[])
{
    double m, n;
    while (cin >> m >> n)
        cout << setprecision(12) <<pow(m, 1/n) << '\n';
    return 0;
}

发表于 2021-06-30 22:35:30 回复(0)
牛顿法+快速幂
#include <iostream>
#include <stdio.h>

using namespace std;

long double myabs(long double x){
    if(x < 0)
        return -x;
    else
        return x;
}

long double mypow(long double a, int b){
    long double res = 1.0;
    while(b > 0){
        if(b & 1){
            res = res * a;
        }
        a = a * a;
        b = b >> 1;
    }
    return res;
}

int main(void){
    long double m , n;
    cin >> m >> n;
    long double x = 1.0;
    while(myabs(mypow(x,n) - m) > 0.0000000000001){
        long double t = mypow(x, n - 1);
        x = x - (t * x - m)/(n * t);
    }
    printf("%.12Lf\n",x);
    return 0;
}


发表于 2021-06-29 09:57:39 回复(0)
java用快速幂求n次方,用二分逼近目标数。
import java.util.Scanner;
public class Main {
    public static double quickMul(double x, int N) {
        if (N == 0) {
            return 1.0;
        }
        double y = quickMul(x, N / 2);
        return N % 2 == 0 ? y * y : y * y * x;
    }
    
    public static double mySqrt(double m, int n){
        double eps = 10E-14;
        double l = 0;
        double r = m;
        while(Math.abs(r-l)>=eps){
            double mid= l+(r-l)/2;
            double tmp=quickMul(mid,n);
            if(tmp>m){
                r=mid;
            }else{
                l=mid;
            }
        }
        return l;        
    }
    
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        while(sc.hasNext()){
            double m = sc.nextDouble();
            int n = sc.nextInt();
            System.out.println(mySqrt(m, n));
        }
    }
}


发表于 2020-11-03 18:17:27 回复(0)
#include<iostream>
#include<cstdio>
 
using namespace std;
 
double fun(double n, double x, double m) {
    double xn = 1.0;
    for(int i=0; i<((int)n)-1; ++i) {
        xn *= x;
    }
    return 1.0/n*((n-1)*x + m/xn);
}
 
int main() {
    double m, n;
    cin >> m >> n;
    if(m == 0) {
        printf("%.12f", m);
    } else {
        double x = m;
        double y = m;
        do {
            y = x;
            x = fun(n, y, m);
        } while(x!=y);
        printf("%.12f", y);
    }
     
    return 0;
}
迭代法
发表于 2020-10-13 20:37:09 回复(0)
import java.util.*;
public class Main{
    public static void main(String[] args){
        Scanner sc = new Scanner(System.in);
        Main main = new Main();
        double n = sc.nextDouble();
        int m = sc.nextInt();
        
        System.out.println(main.mySqrt(n, m));
    }
    private double mySqrt(double n, int m){
        /*
                我这里输入跟题目给的不一样,n 是 m,而 m 是 n
        我们使用二分逼近的方法
        首先 mid = (left + right) >>> 1;
        然后将 n 除以 mid ,m - 1 次
        为啥?因为我们要跟 mid 进行比较,判断 mid 是否是适合 n 开 m 次方后的数
        比如 n 开方,那么我们只需要 n 除以 mid 一次即可,然后将结果跟 mid 比较
        如果接近,那么继续逼近
        同时,我们可以换做是 m 个 mid 相乘,然后跟 n 进行比较,一样的思路
        只不过一个是乘,一个是除
        */
        double pre = 0;
        double left = 0;
        double right = n;
        //迭代精准度
        double eps = 1e-12;
        while(right - left > eps || left - right > eps){
            double mid = (left + right) / 2;
            double temp = 1;
            for(int i = 0; i < m; i++){
                temp *= mid;
            }
            if(temp > n){
                right = mid;
            }else{
                left = mid;
            }
            pre = mid;
        }
        return pre;
    }
}

编辑于 2020-08-15 21:09:56 回复(0)
python 3的解法,注意m是float
if __name__ == '__main__':
    m, n = list(map(float, input().split()))
    n = int(n)

    left = 0
    right = m
    midpre = 0
    mid = 0
    while left < right:
        mid = (right - left) / 2 + left
        sum_num = 1
        for i in range(n):
            sum_num *= mid

        if abs(mid - midpre) < 1e-13:
            break
        elif sum_num > m:
            right = mid
        else:
            left = mid
        midpre = mid

    print("%.12f" % mid)


发表于 2020-07-06 19:41:27 回复(1)
import java.util.Scanner;
public class Main {
    public static void main(String[] args) {
        Scanner scan = new Scanner(System.in);
        while (scan.hasNextLine()){
            String nextline = scan.nextLine();
            String[] nextdata = nextline.split(" ");
            if (nextdata.length < 2){
                break;
            }
            Double m = new Double(nextdata[0]);
            Integer n = new Integer(nextdata[1]);
            int time = 1;
            double rst = 1.0, test = 0.1;
            for (int i = 0; m - exp(rst, n) > 0; rst++);
            //求出整数部分
            rst--;
            for(int i = 0; m - exp(rst, n) != 0 && test != 0; test /= 10){
                for (int j = 0; m - exp(rst + test, n) > 0 && j < 10; rst = rst + test, j++);
            }
            System.out.println(rst);
        }
    }
    public static double exp(double num, int e){
        double rst = 1.0;
        for (int i= 0; i < e; i++){
            rst *= num;
        }
        return rst;
    }
}
发表于 2020-03-21 18:42:48 回复(0)
def root3(n,num):
    acc=10**(-14)
    low=0
    high=num
    while(high-low>=acc):
        mid=(low+high)/2.0
        #prod=1
          #for j in range(n): # mid multiply n times
         #prod=prod*mid
        prod=mid**n
        if(abs(prod-num)<=acc):
            break
        if(prod>=num): high=mid
        else: low=mid

    print("%.12f"%mid)

if __name__ == "__main__":
    num,n=map(int,input().strip().split())
    root3(n,num)

这代码错哪了,竟然不能100%通过。
编辑于 2020-03-11 14:32:07 回复(2)
import java.util.*;

public class Main {
	static double d = 10e-12;

	public static double sqrt(double m, int n) {
		double left = 0;
		double right = m;
		while (right - left > d) {
			double mid = left + (right - left) / 2;
			double tmp = getX(mid, n);
			if (tmp > m) {
				right = mid;
			} else {
				left = mid;
			}
		}
		return right;

	}

	public static double getX(double x, int n) {
		double s = 1.0;

		for (int i = 0; i < n; i++) {
			s = s * x;
		}
		return s;
	}

	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		double i = sc.nextDouble();
		int n = sc.nextInt();

		System.out.println(sqrt(i, n));

	}

}

发表于 2020-02-21 23:14:59 回复(0)