首页 > 技术文章 > HDU 5105 Math Problem

liuweimingcprogram 2016-08-09 18:31 原文

http://acm.hdu.edu.cn/showproblem.php?pid=5105

题意就是给出一条三次函数,f(x)=|a*x^3+b*x^2+c+d|。和给定一个区间[L,R],问你这个函数在这个区间里面的最大值。

刚开始做的时候,想到是三分答案的,不久前做个一题二次函数的,固定一个点p求最短距离,用的是三分答案。但是这题是三次函数,而且求的是函数上的最大值。所以三分答案是错误的。

然后正解就是直接求导,判断f(L),f(R)和极值点即可。这里要注意分类讨论。

因为a=0的时候不是三次函数,直接用二次函数对称轴判断即可,

然后b=0的时候是一次函数。。等等。其实就是要特判啦。

#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <algorithm>
using namespace std;
#define inf (0x3f3f3f3f)
typedef long long int LL;

#include <iostream>
#include <sstream>
#include <vector>
#include <set>
#include <map>
#include <queue>
#include <string>
#define eps 1e-7

double a,b,c,d,L,R;
double f (double x)
{
    return fabs(a*x*x*x+b*x*x+c*x+d);
}
int same(double a,double b)
{
    return fabs(a-b)<eps;
}
void work ()
{
    double fL = fabs(f(L));
    double fR = fabs(f(R));
    if (!same(a,0))
    {
        double diaota = 4*b*b-12*a*c;
        if (diaota<0)
        {
            printf ("%0.2f\n",max(fL,fR));
        }
        else
        {
            double x1 = (-2*b-sqrt(diaota))/(6*a);
            double x2 = (-2*b+sqrt(diaota))/(6*a);
//        double f1 = fabs(f(x1));
//        double f2 = fabs(f(x2));
//        double t=max(f1,f2);
//        double t2=max(fL,fR);
//        double ans = max(t,t2);
//        printf ("%0.2f\n",ans);
            double f1;
            double f2;
            int flag1=0;
            int flag2=0;
            if (x1>=L && x1<=R)
            {
                flag1=1;
                f1=fabs(f(x1));
            }
            if(x2>=L&&x2<=R)
            {
                flag2=1;
                f2=fabs(f(x2));
            }
            double ans=max(fL,fR);
            if (flag1) ans=max(ans,f1);
            if (flag2) ans=max(ans,f2);
            printf ("%0.2f\n",ans);
        }
    }
    else if (!same(b,0))
    {
        double x1 = c/(-2*b);
        double ans=max(fL,fR);
        if (x1>=L&&x1<=R)
        {
            ans=max(ans,f(x1));
        }
        printf ("%0.2f\n",ans);
    }
    else if (!same(c,0))
    {
        double ans=max(fL,fR);
        printf ("%0.2f\n",ans);
    }
    else
    {
        printf ("%0.2f\n",d);
    }
}
int main()
{
#ifdef local
    freopen("data.txt","r",stdin);
#endif
    while(scanf("%lf%lf%lf%lf%lf%lf",&a,&b,&c,&d,&L,&R)!=EOF) work();
    return 0;
}
View Code

 

推荐阅读