[Swust OJ 566]--开N方数(牛顿切线法解高次方程)

 

题目链接:http://acm.swust.edu.cn/problem/0566/

 

Time limit(ms): 1000      Memory limit(kb): 65535
 
Description
你见过猪走路,但肯定没有开过N方数。开方运算在科学计算中非常重要.那么现在你也想来挑战一下开N方数(1<=N<=100).只不过,这次的N方数是的要求是:要求截取小数点后M位(1<=M<=8).如:2的1/10方数,截取其4位是:1.0717,而没有四舍五入成为1.0718 
输入的被开方数NUM(0<=NUM<=1000),你可以用计算器来检验你的结果是否正确,记住是截取位数,不能四舍五入!
 
Input
第一行为测试数据个数 
以后每行三个数依次为被开方数NUM,方数N,精确的小数位数M(0 =< M <= 8). 
 
Output
计算出的结果,每个结果占一行
 
Sample Input
5
1000 100 8
90 17 5
30 20 7
10 10 8
29 29 4

Sample Output
1.07151930
1.30303
1.1853758
1.25892541
1.1231

 
Hint 
用牛顿切线法列个方程来解
 
 
解题思路:直接一个数学题构造方程x^n=num(x是结果,方程的解) 
     关于牛顿切线法给出两个链接: (1)http://www.doc88.com/p-406549410439.html (2)http://www.docin.com/p-115591122.html
 
那么构造f(x)=x^n-num
    f`(x)=n*x^(n-1)
    x=x0-f(x)/f`(x),化简整理可得x=num^(1/n);
 
当然值得注意的是这里是截取小数后几位,不是四舍五入,那么不能用%.f来控制,我这里采用sprintf转换为字符
 
代码如下:
 1 #include <iostream>

 2 #include <cmath>

 3 #include <cstdio>

 4 #include <cstring>

 5 using namespace std;

 6 int main(){

 7     double ans;

 8     int x, n, t, k, i, j, len;

 9     cin >> t;

10     while (t--){

11         char str[100];

12         cin >> x >> n >> k;

13         ans = pow(x*1.0, 1 * 1.0 / n);

14         //cout<<ans<<endl;

15         sprintf(str, "%.10lf", ans);

16         len = strlen(str);

17         //cout<<str<<endl;

18         for (i = 0; i < len; i++){

19             if (str[i] == '.') {

20                 cout << '.';

21                 j = 0;

22                 while ((j++) < k)

23                     cout << str[i + j];

24                 break;

25             }

26             cout << str[i];

27         }

28         cout << endl;

29     }

30     return 0;

31 }
View Code

 

不过好像我被hint坑了,貌似开n次方就直接1/n次幂~~~(就当补了下数学吧,以后高次方程会搞了,无爱了,万恶的hint~~~)

你可能感兴趣的:(OJ)