10341 - Solve It

Time limit: 3.000 seconds

http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&category=113&page=show_problem&problem=1282

Solve the equation:
p *e - x + q *sin( x ) + r *cos( x ) + s *tan( x ) + t * x 2 + u = 0
where 0 <= x <= 1 .

Input

Input consists of multiple test cases and terminated by an EOF. Each test case consists of 6 integers in a single line: p , q , r , s , t and u (where 0 <= p , r <= 20 and -20 <= q , s , t <= 0 ). There will be maximum 2100 lines in the input file.

Output

For each set of input, there should be a line containing the value of x , correct upto 4 decimal places, or the string " No solution ", whichever is applicable.

Sample Input

0 0 0 0 -2 1
1 0 0 0 -1 2
1 -1 1 -1 -1 1

Sample Output

0.7071
No solution
0.7554

参考: 维基百科——牛顿法

1. 根据系数的范围知道方程左端是递减的。(可以使用零点定理)

2. 如果f'(x)不为0, 那么牛顿法将具有平方收敛的性能.。粗略的说,这意味着每迭代一次,牛顿法结果的有效数字将增加一倍。

PS:你也可以用二分法,只不过慢一点而已。

完整代码:

/*0.019s*/
#include <cstdio>
#include <cmath>
int p, q, r, s, t, u;
double x;
inline double fun(double x)
	return p * exp(-x) + q * sin(x) + r * cos(x) + s * tan(x) + t * x * x + u;
///导数
inline double fun2(double x)
	return -p * exp(-x) + q * cos(x) - r * sin(x) + s / (cos(x) * cos(x)) + 2 * t * x;
int main(void)
	while (~scanf("%d%d%d%d%d%d", &p, &q, &r, &s, &t, &u))
		double x1 = fun(0.0), x2 = fun(1.0);
		if (x1 == 0)
			puts("0.0000");
			continue;
		if (x2 == 0)
			puts("1.0000");
			continue;
		if (x1 * x2 > 0)
			puts("No solution");
			continue;
		x = 0.5;///从0.5开始
		double tmp = 0.0;
		while (fabs(x - tmp) > 1e-3)///想保险点的话可以写1e-6(保两位)
			tmp = x;
			x -= fun(x) / fun2(x);
		printf("%.4f\n", x);
	return 0;
                                    32016-05-26 20:08:05 +08:00   1#!/usr/bin/python3from math import log, exp## ln(f)=ln(p)+q1*f=ln(p)+q1*exp[ln(f)]def f(p,q):lp=log(p)epsilon=1e-5## initial guessy0=0y1=1while (y1-y0)>epsilon or (y...
                                    原作者:郑丰华%对solve指令的使用%对线性,非线性,超越方程的求%--------------------------------------------------------------------------%当方程组不存在符号时,若又无其他自由参数,%则solve将给出数值.%solve(S)                   对一个方程默认变量求%solve(S,v)   ...
                                    共回答了26个问题采纳率:92.3%使用二分上面超越方程下面是二分的函数文件,你直接设置输入参数就可以了function [c,err,yc]=bisect(f,a,b,delta)%Input - f is the function% - a and b are the left and right endpoints% - delta is the tolerance%Output ...
                                    有时候我们要数值求超越方程的多个根,但是数值方都要给定一个初值。
matlab有内建函数fsolve非线性方程(组),但是只能求一组给定初值的,如果要求多个根(如频率方程),可以先用mathematica画图,然后观察得到零点个数和大概位置,然后调用fsolve。
这里提供了一个程序,在区间(a,b)上面画图,然后可以用鼠标选取n个点,然后返回以这些点作为初值得到的根。...