HDU 2199 Can you solve this equation? 牛顿迭代法 || 二分

来源:互联网 发布:javascript 转义符 编辑:程序博客网 时间:2024/06/08 19:12

,###题目
http://acm.hdu.edu.cn/showproblem.php?pid=2199

题意:

给出方程如下:8x4+7x3+2x2+3x+6==Y,求这个方程在[0,100]这个区间内的最小解

思路:

由于给定的方程和定义域可知,函数在定义域内是单调的,因此可以二分答案判断是否可行。另外更通用的一种方式是用牛顿迭代法,把方程改写成8x4+7x3+2x2+3x+6Y==0
二分:

#include <bits/stdc++.h>using namespace std;typedef long long ll;const int N = 50010;const double eps = 1e-6;double f(double m){    return 8 * pow(m, 4) + 7 * pow(m, 3) + 2 * pow(m, 2) + 3 * m + 6;}int main(){    int t;    scanf("%d", &t);    while(t--)    {        double n;        scanf("%lf", &n);        double l = 0.0, r = 100.0, res = -1;        for(int i = 1; i <= 100; i++)        {            double mid = (l + r) / 2;            double tmp = f(mid);            if(tmp >= n) r = mid, res = mid;            else l = mid;        }        if(fabs(f(res) - n) > eps) printf("No solution!\n");//用这条语句判断是否有解时,注意eps的问题,1e-6可过,1e-8不可过,精度真是蛋疼        //if(n < f(0) || n > f(100)) printf("No solution!\n");        else printf("%.4f\n", res);    }    return 0;}

牛顿迭代法:

#include <bits/stdc++.h>using namespace std;const int N = 1000 + 10, INF = 0x3f3f3f3f;const double eps = 1e-6;double y;double df(double x) //函数的导数{    return 32*x*x*x + 21*x*x + 4*x + 3;}double f(double x) //函数{    return 8*x*x*x*x + 7*x*x*x + 2*x*x + 3*x + 6 - y;}double newton_iteration(double x){    int tot = 0;    while(fabs(f(x) - 0) > eps)    {        x = x - f(x) / df(x);        if(++tot >= 30) return -1;//超过给定次数则认为无解    }    return x;}int main(){    int t;    scanf("%d", &t);    while(t--)    {        scanf("%lf", &y);        bool flag = false;        double ans = 0.0;        for(int i = 0; i <= 100; i++)//多选几个初始点进行迭代求解,避免出现随机性的错误,经测试直接选0不可过,选50可过        {            ans = newton_iteration(i);            if(ans >= 0 && ans <= 100)            {                flag = true; break;            }        }        if(flag) printf("%.4f\n", ans);        else puts("No solution!");    }    return 0;}
原创粉丝点击