#1142 : 三分·三分求极值
时间限制:10000ms
单点时限:1000ms
内存限制:256MB
描述
这一次我们就简单一点了,题目在此:
输入
第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; }