1. 程式人生 > >hdu 3400-三分套三分

hdu 3400-三分套三分

此題嚴格證明方法確實暫時不會,一開始想象成凹函式和單調函式的和但是沒法嚴格證明,因為多元函式不知道是否涉及偏導數,回去翻翻高數書要是證明了來填坑。

說說這個題的坑在於一開始三分的時候用點來判斷三分結束,但是發現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;
}