bzoj1857: [Scoi2010]传送带

6 篇文章 0 订阅

看到这题第一感觉暴力呀233

然后就乱搞水过了(数据太水?)

我的做法是将AB,CD分别等分为512段

这样AB,CD上各有513个顶点,不妨设AB上的顶点为E,CD上的顶点为F

通过数学容易得到A到D的最短时间移动路径是AE-EF-FD,

那枚举E在AB上那513个顶点位置,枚举F在CD上那513个顶点位置,

其中满足AE/P+FD/Q+EF/R最小的E,F点时路径移动时间最短,此时AE/P+FD/Q+EF/R就是答案

由于线段长度有限,取512段基本可以满足精度问题

听神犇说这题是三分?我表示一脸懵逼2333

#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<cstdlib>
using namespace std;
int ax,ay,bx,by,cx,cy,dx,dy;
int p,q,r;
int tza=0,tzb=0;
double ka,kb,ba,bb;
double sum=0,ans=0x3f3f3f3f;
struct data{
       double xi,yi;
}op[2005],kp[2005];
int cnt=2,tot=2;
void find(double axx,double ayy,double bxx,double byy,int timm)
{
     if(timm>8)return ;
     double oxx,oyy;
     oxx=(axx+bxx)/2.0;
     oyy=(ayy+byy)/2.0;
     cnt++;
     op[cnt].xi=oxx;
     op[cnt].yi=oyy;
     find(axx,ayy,oxx,oyy,timm+1);
     find(oxx,oyy,bxx,byy,timm+1);
}
void seach(double axx,double ayy,double bxx,double byy,int timm)
{
     if(timm>8)return ;
     double oxx,oyy;
     oxx=(axx+bxx)/2.0;
     oyy=(ayy+byy)/2.0;
     tot++;
     kp[tot].xi=oxx;
     kp[tot].yi=oyy;
     seach(axx,ayy,oxx,oyy,timm+1);
     seach(oxx,oyy,bxx,byy,timm+1);
}
void lcr(int x,int y)
{
     double lena,lenb,lenc;
     lena=sqrt((kp[x].xi-ax)*(kp[x].xi-ax)+(kp[x].yi-ay)*(kp[x].yi-ay));
     lena/=(double)p;
     lenb=sqrt((op[y].xi-dx)*(op[y].xi-dx)+(op[y].yi-dy)*(op[y].yi-dy));
     lenb/=(double)q;
     lenc=sqrt((kp[x].xi-op[y].xi)*(kp[x].xi-op[y].xi)+(kp[x].yi-op[y].yi)*(kp[x].yi-op[y].yi));
     lenc/=(double)r;
     sum=(lena+lenb+lenc);
     ans=min(sum,ans);
}
int main()
{
    int i,j,k,l;
    scanf("%d%d%d%d",&ax,&ay,&bx,&by);
    scanf("%d%d%d%d",&cx,&cy,&dx,&dy);
    scanf("%d%d%d",&p,&q,&r);
    op[1].xi=cx;op[1].yi=cy;
    op[2].xi=dx;op[2].yi=dy;
    find(cx,cy,dx,dy,0);
    kp[1].xi=ax;kp[1].yi=ay;
    kp[2].xi=bx;kp[2].yi=by;
    seach(ax,ay,bx,by,0);
    for(i=1;i<=tot;i++){
        for(j=1;j<=cnt;j++){
            lcr(i,j);
            }
        }
    printf("%.2lf",ans);
    return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值