hihocoder 1142 三分求极值【三分算法 模板应用】

#1142 : 三分·三分求极值

时间限制:10000ms
单点时限:1000ms
内存限制:256MB

描述

这一次我们就简单一点了,题目在此:

在直角坐标系中有一条抛物线y=ax^2+bx+c和一个点P(x,y),求点P到抛物线的最短距离d。

提示:三分法

输入

第1行:5个整数a,b,c,x,y。前三个数构成抛物线的参数,后两个数x,y表示P点坐标。-200≤a,b,c,x,y≤200

输出

第1行:1个实数d,保留3位小数(四舍五入)

样例输入
2 8 2 -2 6
样例输出
2.437

算法分析:给你一条凸性曲线,给你一点p(x,y),让你计算这条曲线上的某点到这个p点的最近距离。
采用三分算法,思路:我们将最大区间定为[left, right],我们不断的三分枚举这个区间,直到
最小。 首先将区间三分:mid=(left+right)/2; midmid=(mid+right)/2;(并非是严格的三)
等分。我们比较calc(mid)与 calc(midmid)的值,来判断接下来的区间逼近过程该向哪个区间逼近。

代码:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
#include <math.h>
#include <iostream>
#include <string>
#include <queue>
#include <stack>
#include <algorithm>
#define N 100000+100
#define M 60000+100
#define INF 0x3f3f3f3f
#define eps 1e-8

using namespace std;

int a, b, c, x, y;

double calc(double x)
{
    return a*x*x+b*x+c;
} //获取函数的y值

double dist(double dd)
{
    return (dd-x)*(dd-x)+(calc(dd)-y)*(calc(dd)-y);
} //获取函数曲线上的点到线外一点的距离

void Three_search()
{
    double left, right;
    double mid, midmid;
    double mid_value, midmid_value;
    left=-200.0; right=200;

    while(left+eps<right)
    {
        mid = (left+right)/2; mid_value=dist(mid);
        midmid=(mid+right)/2; midmid_value=dist(midmid);

        if(mid_value>=midmid_value )
        {
            left=mid; //区间逼近
        }else{
            right=midmid;//区间逼近
        }
    }
    double ans=dist(left);
         //此时的left与right已经逼近到值几乎相同了
    ans = sqrt(ans);

    printf("%.3lf
", ans );
}

int main()
{

    scanf("%d %d %d %d %d", &a, &b, &c, &x, &y);
    Three_search();

    return 0;
}

原文地址:https://www.cnblogs.com/yspworld/p/4664808.html