[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~~~)

posted @ 2015-06-17 14:48  繁夜  阅读(778)  评论(2编辑  收藏  举报