hdu3400 Line belt

单峰函数求极小值问题。。。果断三分法。。。

在ab段找一点m1,在cd段找一点m2,则 t=length(a,m1)/p+length(m1,m2)/r+length(m2,d)/q;

在外层对ab段三分,在内层对cd三分,求最小值。

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<math.h>
#include<float.h> 
#define esp  1e-6 
//双三分法(两层)求函数极值
struct point
{
  double x,y; 
}A,B,C,D; 
int p,q,r;
double len(struct point a,struct point b)
{
  return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));       

double solve1(struct point m)                  //对CD段三分
{
    double t1,t2;
    struct point left,right,mid,midmid; 
    left=C;  
    right=D;  
    do{
      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; 
      t1=len(m,mid)/r+len(mid,D)/q;  
      t2=len(m,midmid)/r+len(midmid,D)/q;   
      if(t1<t2)   right=midmid;
      else        left=mid;             
    }while(fabs(t1-t2)>=esp);     
    return t1;       

double solve2()                         //对AB段三分
{
  double t1,t2;
  struct point left,right,mid,midmid;
  left.x=A.x; left.y=A.y;  
  right.x=B.x; right.y=B.y;  
  do{
    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;
    t1=len(A,mid)/p+solve1(mid); 
    t2=len(A,midmid)/p+solve1(midmid);
    if(t1<t2)     right=midmid;    //求解最小值                    
    else          left=mid; 
  }while(fabs(t1-t2)>=esp);      
  return t1;     

int main()
{
  int t,i,j,k; 
  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("%d %d %d",&p,&q,&r);
    printf("%.2lf\n",solve2());
  }
  //system("pause");
  return 0;    
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值