此题严格证明方法确实暂时不会,一开始想象成凹函数和单调函数的和但是没法严格证明,因为多元函数不知道是否涉及偏导数,回去翻翻高数书要是证明了来填坑。
说说这个题的坑在于一开始三分的时候用点来判断三分结束,但是发现sqrt精度丢失问题似乎比较严重,后来用mid_v和midmid_v来判断就1A了,精度问题果然还是搞不懂。
被精度卡了很多次现在至今学不会,蒟蒻真是伤不起啊。下面贴代码。
#include <iostream> #include <cmath> #include <algorithm> using namespace std; const double EPS=1e-8; double R,Q,P,ans; double L1,L2; struct Point{ double x,y; }; Point A,B,C,D; double dis(Point p1,Point p2){ return sqrt((p1.x-p2.x)*(p1.x-p2.x)+(p1.y-p2.y)*(p1.y-p2.y)+1e-9); } double BSolve(Point MIN,Point MAX,Point AA){ Point Left,Right; Point mid, midmid; double mid_value=999, midmid_value=0; Left.x = MIN.x; Left.y = MIN.y; Right.x = MAX.x; Right.y = MAX.y; while (abs(mid_value - midmid_value)>EPS ) { mid.x = (Left.x + Right.x) / 2.0; mid.y = (Left.y + Right.y) / 2.0; midmid.x = (mid.x + Right.x) / 2.0; midmid.y = (mid.y + Right.y) / 2.0; mid_value = dis(mid,D)/Q+dis(AA,mid)/R; midmid_value = dis(midmid,D)/Q+dis(AA,midmid)/R; // 假设求解最大极值. if (mid_value <= midmid_value) Right = midmid; else Left = mid; } return mid_value; } double ACalc(Point a) { return BSolve(C,D,a); } void ASolve(Point MIN,Point MAX){ Point Left,Right; Point mid, midmid; double mid_value=999, midmid_value=0; Left.x = MIN.x; Left.y = MIN.y; Right.x = MAX.x; Right.y = MAX.y; while (abs(mid_value - midmid_value)>EPS ) { mid.x = (Left.x + Right.x) / 2; mid.y = (Left.y + Right.y) / 2; midmid.x = (mid.x + Right.x) / 2; midmid.y = (mid.y + Right.y) / 2; mid_value = dis(mid,A)/P+ACalc(mid); midmid_value = dis(midmid,A)/P+ACalc(midmid); // 假设求解最大极值. if (mid_value <= midmid_value) Right = midmid; else Left = mid; //cout<<mid_value<<endl; } printf("%.2f\n",mid_value); } int main() { int t; cin>>t; while(t--){ cin>>A.x>>A.y>>B.x>>B.y>>C.x>>C.y>>D.x>>D.y>>P>>Q>>R; ASolve(A,B); } return 0; }