hdu 3400(三分)

题目链接:点击打开链接

题意:本题给出两条线段,一条线段端点为a,b;另一条线段端点是c,d,在两条线段和不在线段上有不同的速度,求最短时间。

分析:本题一共有三段时间,在a-b上,在c-d上,在空白的地方。设着三段时间是x,y,z。则一旦x和y确定之后,z就能确定,因为这样在两线段上的点就确定了,z也就求出来了,如果x确定时y不确定的话,z和y有关系,所以时间是有一个极值,想到极值,就应该三分求最适合的y。而对于x来说,三分求解x的话可以搞出对应点的y的极值,也就能求出队应的y的极值。这是就解出来了。

代码如下:

#include <math.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <iostream>
#include <algorithm>
using namespace std;
const double eps=1e-7;
const double ee=1e-9;
struct Point{
    double x,y;
};
double dis(Point a,Point b){
    return sqrt(ee+(a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));
}
double q,p,r;
Point a,b,c,d,tmpx,tmpy;
double call(double t){
    tmpy.x=d.x+(c.x-d.x)/dis(c,d)*t*q;
    tmpy.y=d.y+(c.y-d.y)/dis(c,d)*t*q;
    return t+dis(tmpx,tmpy)/r;
}
double sanfen(double t){
    tmpx.x=a.x+(b.x-a.x)/dis(a,b)*t*p;
    tmpx.y=a.y+(b.y-a.y)/dis(a,b)*t*p;
    double low,high,mid,midd;
    low=0;
    high=dis(c,d)/q;
    while(high-low>eps){
        mid=(low+high)/2;
        midd=(mid+high)/2;
        if(call(mid)<call(midd))high=midd;
        else low=mid;
    }
    return t+call(mid);
}                                      //三分求y值
int main(){
    int t;
    scanf("%d",&t);
    while(t--){
        scanf("%lf%lf%lf%lf",&a.x,&a.y,&b.x,&b.y);
        scanf("%lf%lf%lf%lf",&c.x,&c.y,&d.x,&d.y);
        scanf("%lf%lf%lf",&p,&q,&r);
        double low,high,mid,midd;
        low=0;
        high=dis(a,b)/p;
        while(high-low>eps){
            mid=(low+high)/2;
            midd=(mid+high)/2;
            if(sanfen(mid)<sanfen(midd))high=midd;
            else low=mid;
        }                                   //三分求x的值
        printf("%.2f\n",sanfen(mid));
    }
    return 0;
}
时间: 2024-10-29 04:03:19

hdu 3400(三分)的相关文章

hdu 2899 hdu 3400 三分/几何

hdu2899 : 水提,直接三分,其实求导后二分也可以. #include<iostream> #include<cstdio> using namespace std; double y; double inline f( long double x) { return 6*x*x*x*x*x*x*x+8*x*x*x*x*x*x+7*x*x*x+5*x*x-y*x; } int main() { int T;scanf("%d",&T); while

HDU 3400 Line belt 三分

笨蛋的难题(一) 时间限制:1000 ms  |  内存限制:65535 KB 难度:1 描述        笨蛋之所以称为笨蛋,是因为他有点路痴.他一旦不高兴,就必然一个人漫无目的的出去走走.今天下雨了,他又不高兴了,怎么办?那就出去走呗,这不又丢了,这次幸好记下出来时的方向,并且在一张纸上密密麻麻的记下了他拐的弯(他很聪明吧,拐的弯都是90度的弯),0代表左拐,1代表右拐,那么多0.1,他实在看不下去了,正好遇见善良加聪明的你,你能告诉他,他现在面向哪吗? 输入 多组测试数据 第一行 输入:

HDU 3400 Line belt (三分再三分)

HDU 3400 Line belt (三分再三分) ACM 题目地址: HDU 3400 Line belt 题意: 就是给你两条线段AB , CD ,一个人在AB以速度p跑,在CD上以q跑,在其他地方跑速度是r.问你从A到D最少的时间. 分析: 先三分AB上的点,再三分CD上的点即可. 证明: 设E在AB上,F在CD上. 令人在线段AB上花的时间为:f = AE / p,人走完Z和Y所花的时间为:g = EF / r + FD / q. f函数是一个单调递增的函数,而g很明显是一个先递减后递

HDU 5144 三分

开始推导用公式求了好久(真的蠢),发现精度有点不够. 其实这种凸线上求点类的应该上三分法的,当作入门吧... /** @Date : 2017-09-23 21:15:57 * @FileName: HDU 5144 三分 无聊物理题.cpp * @Platform: Windows * @Author : Lweleth ([email protected]) * @Link : https://github.com/ * @Version : $Id$ */ #include <bits/s

HDU 3400 Line belt (三分嵌套)

题目链接 Line belt Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 2862    Accepted Submission(s): 1099 Problem Description In a two-dimensional plane there are two line belts, there are two segment

三分套三分 --- HDU 3400 Line belt

Line belt Problem's Link:    Mean: 给出两条平行的线段AB, CD,然后一个人在线段AB的A点出发,走向D点,其中,人在线段AB上的速度为P, 在线段CD上的速度为Q,在其他地方的速度为R,求人从A点到D点的最短时间. analyse: 经典的三分套三分. 首先在AB线段上三分,确定一个点,然后再在CD上三分,确定第二个点,计算出answer.也就是嵌套的三分搜索. Time complexity: O(logn*logm) Source code:  // M

搜索(三分):HDU 3400 Line belt

Line belt Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 3531    Accepted Submission(s): 1364 Problem Description In a two-dimensional plane there are two line belts, there are two segments AB

【HDU 3400】Line belt(三分法)

题目链接 题目链接 http://acm.hdu.edu.cn/showproblem.php?pid=3400 题意 有两条传送带AB和CD,移动速度分别为p,q. 除了传送带的其他区域移动速度为r,问A到D最短时间. 题目分析 在AB上找一点E,在CD上找一点F. 使得A->E->F->D时间最短. 数学思路 时间 time = |AE|/p + |EF|/r + |FD|/q. (|AE|为线段AE的长度.) 未知量有E的位置和F的位置,由于确定在AB和CD上,所以只需要两个未知量

hdu 4717(三分) The Moving Points

链接:http://acm.hdu.edu.cn/showproblem.php?pid=4717 n个点,给出初始坐标和移动的速度和移动的方向,求在哪一时刻任意两点之间的距离的最大值的最小. 对于最大值的最小问题首先就会想到二分,然而由于两点之间的距离是呈抛物线状,所以三分的方法又浮上脑海,当然二分也可以做,不过思维上更复杂一些 1 #include<cmath> 2 #include<cstdio> 3 #include<cstring> 4 #include<