2013-07-05 16:20:33Morris

[UVA][牛頓法] 10428 - The Roots

Problem J
The Roots
Input: standard input
Output: standard output
Time Limit: 15 seconds

A polynomial equation has the following form:

 

                 anxn + an-1xn-1 + an-2xn-2 + … + a1x1+ a0 = 0

 

Here X is variable and an, an-1 etc are known as coefficient.  So to specify a polynomial equation we need the values of the coefficients only. The roots of a polynomial equation are the values of X for which the value of LHS is zero. In this problem you will have to find the roots of a polynomial equation. You can assume that a polynomial equation of degree n should have n real roots and all the roots are strictly different.

 

Input

The input file contains less than 5001 lines of input.

 

Each line contains an integer N (N<=5) followed by (N+1) floating point numbers. Here N is the order of the polynomial equation. The next (N+1) numbers denote the values of an, an-1, an-2  …, a1 and a0. These absolute values of these coefficients will be less than 1e9 or 1000000000 and the absolute values of the roots will be less than 25.  So each line contains information about one polynomial equation.

 

Input is terminated by a line where N=0.

 

Output

For each line of input produce one line of output. This line starts with the string “Equation S:” here S is the output serial number as shown in the sample output. This string is followed by N floating point numbers, which are the roots of the corresponding input equation. The roots should be printed in ascending order of their values and rounded up to four digits after the decimal point. All the root values are preceded by a single space. The judge input is designed in such a way that if your precision is relatively low (values less than 1e-10 are considered as zero) you will face no precision errors. Of course your solution must be correct and you must be well aware of the limitations of different root finding methods.

 

Sample Input
2 1 -9.5750000000 -179.5585140000

4 1 53.3120000000 958.2510390000 6677.1763593480 15733.6254955064

0

 

Sample Output

Equation 1: -9.4420 19.0170

Equation 2: -22.8060 -18.1170 -6.7350 -5.6540


Problem setter: Shahriar Manzoor, ACM Valladolid Online Judge Team

牛頓法 x' = x - f(x)/f'(x) 然後去逼近解。


思考會不會有 -0.0000 的輸出要修正, 導致精準度上要做調整。

找到一個解之後, 用多項式的直式除法(而非長除法)去降次。


#include <stdio.h>
#include <algorithm>
#include <math.h>
using namespace std;
int main() {
    int n, i, j, k;
    int cases = 0;
    while(scanf("%d", &n) == 1 && n) {
        double a[10] = {};
        for(i = n; i >= 0; i--)
            scanf("%lf", &a[i]);
        double ret[10];
        int m = n;
        for(i = 0; i < m; i++) {
            double b[10] = {}; // f'(x)
            for(j = 0; j <= n; j++)
                b[j] = a[j+1]*(j+1);
            double x = 25, tx;//max_value
            if(i)   x = ret[i-1];
            while(true) {
                double fx = 0, ffx = 0;
                for(j = 0; j <= n; j++) {
                    fx += a[j]*pow(x, j);
                    ffx += b[j]*pow(x, j);
                }
                tx = x - fx/ffx;
                if(fabs(fx) < 1e-8)
                    break;
                x = tx;
            }
            ret[i] = x;
            for(j = n; j >= 0; j--)
                a[j] = a[j] + a[j+1]*x;
            for(j = 0; j <= n; j++)
                a[j] = a[j+1];
            n--;
        }
        printf("Equation %d:", ++cases);
        n = m;
        sort(ret, ret+n);
        for(i = 0; i < n; i++)
            printf(" %.4lf", ret[i]);
        puts("");
    }
    return 0;
}
/*
2 1 -9.5750000000 -179.5585140000

4 1 53.3120000000 958.2510390000 6677.1763593480 15733.6254955064

0
*/