[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),你可以用计算器来检验你的结果是否正确,记住是截取位数,不能四舍五入!
输入的被开方数NUM(0<=NUM<=1000),你可以用计算器来检验你的结果是否正确,记住是截取位数,不能四舍五入!
Input
第一行为测试数据个数
以后每行三个数依次为被开方数NUM,方数N,精确的小数位数M(0 =< M <= 8).
以后每行三个数依次为被开方数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 }
不过好像我被hint坑了,貌似开n次方就直接1/n次幂~~~(就当补了下数学吧,以后高次方程会搞了,无爱了,万恶的hint~~~)
如果这是你所爱的,就不要让自己后悔~~~