题意:
Description
给出一个数x,让你计算级数:
1 + x - x^2/2! + x^3/3! - x^4/4! + ... (-1)^(n+1) * x^n/n!
其中a^b表示a的b次方。
Input:
有多组测试数据,对于每组测试,仅包含一个数x。x可能为小数。(-20<=x<=20)
输入到文件结束。
Output:
对于每组测试数据,输出一行,包含一个小数,精确到10-8。
simple input:
1
2
simple output:
1.63212056 1.86466472
Hint:
n从1~无穷大..
思路:
简单的暴力..
就是套用通项公式..
知道套通项算出来的值小于1e-8..就是已经开始收敛了..
这样就算再计算也不会怎么变了..就可以保证是精确到小数点后8位了..
Tips:
当n = 1000的时候~算阶乘就完全没有办法存下了..
但是其实仔细想一下..可以发现x^n/n! 可以化成 x/1 * x/2 * x/3 * x/4 *…… * x/n..
所以直接这么算就不会出错了..
p.s. 才发现原来数据太大用不适合的类型变量来存出问题了也可能导致tle~
还有一个常忘的就是浮点型的表示方法是 十进制数 = 尾数*2^阶码.. 然后精确到小数点后8位表示方法应该是5*1e-9...
对了..这道题还可以用公式~泰勒展式~
Code:
暴力啊暴力..
1 #include <stdio.h> 2 #include <cstring> 3 #include <cmath> 4 using namespace std; 5 #define eps 5*1e-9 6 7 double fun(double x, int n) {///化简..因为如果直接计算n!..当n=1000就存不下了.. 8 double sum = 1; 9 for(int i = 1; i <= n; ++i) { 10 sum *= (double)x/i; 11 } 12 return sum; 13 } 14 15 double cal(double x, int n) { 16 return (n%2 == 0 ? -1:1)*fun(x, n);///这里可以直接根据n的奇偶判断是正否数~一开始很笨地调用了pow.. 17 } 18 19 20 bool check(double n) { 21 if(fabs(n) > eps) return true; 22 else return false; 23 } 24 25 int main() 26 { 27 int i, j, k; 28 double x, sum, ans; 29 while(scanf("%lf", &x) != EOF) {///wa了一次..没留意不一定是int型.. 30 i = 1, 31 sum = 1; 32 ans = cal(x, i); 33 while(check(ans)) { ///当精度少于1e-8..就可看作收敛.. 34 sum += ans; 35 i++; 36 ans = cal(x, i); 37 } 38 printf("%.8lf\n", sum); 39 40 } 41 return 0; 42 }
泰勒展式啊泰勒展式..
1 忘了展式了..囧~~~
题目链接:404...皆因是练习赛~关闭了..