假设S在T左边,那么只能往右或者上下走

f[i]表示S到i点的最短路

f[i]=min(f[j]+dis(i,j)(i能看到j))

判断i能看到j就维护一个上凸壳和一个下凸壳

时间复杂度$O(n^2)$

代码写的有点长…

#include<cstdio>
#include<cmath>
#include<algorithm>
#define N 2010
using namespace std;
struct P{int x,y;P(){}P(int _x,int _y){x=_x,y=_y;}P operator-(const P&a){return P(x-a.x,y-a.y);}};
inline int cross(P a,P b){return a.x*b.y-a.y*b.x;}
inline double dis(P a,P b){return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));}
int n,i,X1[N],Y1[N],X2[N],Y2[N],xs,ys,xt,yt,st,en;
double v,f[N][4],ans,inf=1e9;
inline void call(int x,int y,int p,double&t){
t=inf;
P o(x,y),up(x,y+1),down(x,y-1),tmp;
for(int i=p-1;i>st;i--){
tmp=P(X2[i],Y2[i]);
if(cross(up-o,tmp-o)>=0){//在up下边或者重合
up=tmp;
if(cross(down-o,tmp-o)<=0)t=min(t,f[i][3]+dis(o,tmp));//在down上边或者重合
}
tmp=P(X2[i],Y1[i]);
if(cross(down-o,tmp-o)<=0){//在down上边或者重合
down=tmp;
if(cross(up-o,tmp-o)>=0)t=min(t,f[i][2]+dis(o,tmp));//在up下边或者重合
}
tmp=P(X1[i],Y2[i]);
if(cross(up-o,tmp-o)>=0){//在up下边或者重合
up=tmp;
if(cross(down-o,tmp-o)<=0)t=min(t,f[i][1]+dis(o,tmp));//在down上边或者重合
}
tmp=P(X1[i],Y1[i]);
if(cross(down-o,tmp-o)<=0){//在down上边或者重合
down=tmp;
if(cross(up-o,tmp-o)>=0)t=min(t,f[i][0]+dis(o,tmp));//在up下边或者重合
}
}
tmp=P(X2[st],Y2[st]);
if(cross(up-o,tmp-o)>=0){//在up下边或者重合
up=tmp;
if(cross(down-o,tmp-o)<=0)t=min(t,f[st][3]+dis(o,tmp));//在down上边或者重合
}
tmp=P(X2[st],Y1[st]);
if(cross(down-o,tmp-o)<=0){//在down上边或者重合
down=tmp;
if(cross(up-o,tmp-o)>=0)t=min(t,f[st][2]+dis(o,tmp));//在up下边或者重合
}
tmp=P(xs,ys);
if(cross(up-o,tmp-o)>=0&&cross(down-o,tmp-o)<=0)t=dis(o,tmp);//在up下边或者重合 在down上边或者重合
}
inline void calr(int x,int y,int p,double&t){
t=inf;
P o(x,y),up(x,y+1),down(x,y-1),tmp;
tmp=P(X1[p],Y2[p]);
if(cross(up-o,tmp-o)>=0){//在up下边或者重合
up=tmp;
if(cross(down-o,tmp-o)<=0)t=min(t,f[p][1]+dis(o,tmp));//在down上边或者重合
}
tmp=P(X1[p],Y1[p]);
if(cross(down-o,tmp-o)<=0){//在down上边或者重合
down=tmp;
if(cross(up-o,tmp-o)>=0)t=min(t,f[p][0]+dis(o,tmp));//在up下边或者重合
}
for(int i=p-1;i>st;i--){
tmp=P(X2[i],Y2[i]);
if(cross(up-o,tmp-o)>=0){//在up下边或者重合
up=tmp;
if(cross(down-o,tmp-o)<=0)t=min(t,f[i][3]+dis(o,tmp));//在down上边或者重合
}
tmp=P(X2[i],Y1[i]);
if(cross(down-o,tmp-o)<=0){//在down上边或者重合
down=tmp;
if(cross(up-o,tmp-o)>=0)t=min(t,f[i][2]+dis(o,tmp));//在up下边或者重合
}
tmp=P(X1[i],Y2[i]);
if(cross(up-o,tmp-o)>=0){//在up下边或者重合
up=tmp;
if(cross(down-o,tmp-o)<=0)t=min(t,f[i][1]+dis(o,tmp));//在down上边或者重合
}
tmp=P(X1[i],Y1[i]);
if(cross(down-o,tmp-o)<=0){//在down上边或者重合
down=tmp;
if(cross(up-o,tmp-o)>=0)t=min(t,f[i][0]+dis(o,tmp));//在up下边或者重合
}
}
tmp=P(X2[st],Y2[st]);
if(cross(up-o,tmp-o)>=0){//在up下边或者重合
up=tmp;
if(cross(down-o,tmp-o)<=0)t=min(t,f[st][3]+dis(o,tmp));//在down上边或者重合
}
tmp=P(X2[st],Y1[st]);
if(cross(down-o,tmp-o)<=0){//在down上边或者重合
down=tmp;
if(cross(up-o,tmp-o)>=0)t=min(t,f[st][2]+dis(o,tmp));//在up下边或者重合
}
tmp=P(xs,ys);
if(cross(up-o,tmp-o)>=0&&cross(down-o,tmp-o)<=0)t=dis(o,tmp);//在up下边或者重合 在down上边或者重合
}
int main(){
scanf("%d",&n);
for(i=1;i<=n;i++)scanf("%d%d%d%d",&X1[i],&Y1[i],&X2[i],&Y2[i]);
scanf("%d%d%d%d",&xs,&ys,&xt,&yt);
if(xs>xt)swap(xs,xt),swap(ys,yt);
scanf("%lf",&v);
for(i=1;i<=n;i++)if(X1[i]<=xs&&xs<=X2[i]&&Y1[i]<=ys&&ys<=Y2[i]){st=i;break;}
for(i=n;i;i--)if(X1[i]<=xt&&xt<=X2[i]&&Y1[i]<=yt&&yt<=Y2[i]){en=i;break;}
f[st][2]=dis(P(xs,ys),P(X2[st],Y1[st]));
f[st][3]=dis(P(xs,ys),P(X2[st],Y2[st]));
for(i=st+1;i<en;i++){
call(X1[i],Y1[i],i,f[i][0]);
call(X1[i],Y2[i],i,f[i][1]);
calr(X2[i],Y1[i],i,f[i][2]);
calr(X2[i],Y2[i],i,f[i][3]);
}
call(X1[en],Y1[en],en,f[en][0]);
call(X1[en],Y2[en],en,f[en][1]);
calr(xt,yt,en,ans);
printf("%.10f",ans/v);
return 0;
}

  

Noi2011 : 智能车比赛的更多相关文章

  1. 2433: [Noi2011]智能车比赛 - BZOJ

    Description 新一届智能车大赛在JL大学开始啦!比赛赛道可以看作是由n个矩形区域拼接而成(如下图所示),每个矩形的边都平行于坐标轴,第i个矩形区域的左下角和右上角坐标分别为(xi,1,yi, ...

  2. [NOI2011]智能车比赛 (计算几何 DAG)

    /* 可以发现, 最优路径上的所有拐点, 基本上都满足一定的性质, 也就是说是在矩形上的拐角处 所以我们可以把他们提出来, 单独判断即可 由于我们提出来的不超过2n + 2个点, 我们将其按照x坐标排 ...

  3. [bzoj2433][Noi2011]智能车比赛

    [题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=2433 http://221.192.240.123:8586/JudgeOnline/ ...

  4. 【[NOI2011]智能车比赛】(建图+spfa+坑爹精度)

    过了这题我就想说一声艹,跟这个题死磕了将近6个小时,终于是把这个题死磕出来了.首先看到这个题的第一反应,和当初做过的一个房间最短路比较相似,然后考虑像那个题那样建边,然后跑最短路.(具体建边方法请参考 ...

  5. 【LOJ】#2443. 「NOI2011」智能车比赛

    题解 显然是个\(n^2\)的dp 我们要找每个点不穿过非赛道区域能到达哪些区域的交点 可以通过控制两条向量负责最靠下的上边界,和最靠上的下边界,检查当前点在不在这两条向量之间即可,对于每个点可以\( ...

  6. BZOJ 2433 智能车比赛(计算几何+最短路)

    题目链接:http://61.187.179.132/JudgeOnline/problem.php?id=2433 题意:若干个矩形排成一排(同一个x之上最多有一个矩形),矩形i和i+1相邻.给定两 ...

  7. 智能车学习(十五)——K60野火2013版例程

    一.中断函数注册方法: 1.格式: 配置某个功能的中断 注册中断函数 开启中断 2.一个例子 pit_init_ms(PIT0,);//定时中断初始化 set_vector_handler(PIT0_ ...

  8. K60平台智能车开发工作随手记

    (图片仅为示例,并不一定固定为这种造型) 第十二届全国大学生智能汽车竞赛有一个分项是光电四轮车的竞速(任务A),Seven她们组采购到的配件使用了freescale Crotex-M4内核的CPU,T ...

  9. 【sky第二期--PID算法】--【智能车论坛】

    [sky第二期--PID算法] 想学PID的可以来[智能车论坛]这里有我发布的资料http://bbs.tekbots.eefocus.com/forum.php?mod=viewthread& ...

随机推荐

  1. Linux内核之数据双链表

    导读 Linux 内核中自己实现了双向链表,可以在 include/linux/list.h 找到定义.我们将会首先从双向链表数据结构开始介绍内核里的数据结构.为什么?因为它在内核里使用的很广泛,你只 ...

  2. Cocos2d坐标系转换

    Cocos2d-x坐标系和OpenGL坐标系相同,都是起源于笛卡尔坐标系(高中数学里面那种). 笛卡尔坐标系 笛卡尔坐标系中定义右手系原点在左下角,x向右,y向上,z向外,OpenGL坐标系为笛卡尔右 ...

  3. 在C/C++程序里打印调用栈信息

    我们知道,GDB的backtrace命令可以查看堆栈信息.但很多时候,GDB根本用不上.比如说,在线上环境中可能没有GDB,即使有,也不太可能让我们直接在上面调试.如果能让程序自己输出调用栈,那是最好 ...

  4. Stanford机器学习---第六讲. 怎样选择机器学习方法、系统

    原文:http://blog.csdn.net/abcjennifer/article/details/7797502 本栏目(Machine learning)包括单参数的线性回归.多参数的线性回归 ...

  5. CreateRemoteThread远程线程注入Dll与Hook

    CreateRemoteThread虽然很容易被检测到,但是在有些场合还是挺有用的.每次想用的时候总想着去找以前的代码,现在在这里记录一下. CreateRemoteThread远程注入 DWORD ...

  6. [ruby on rails] 跟我学之(8)修改数据

    修改views 修改index视图(app/views/posts/index.html.erb),添加编辑链接,如下: <h1>Our blogs</h1> <% @p ...

  7. 1-2+3-4+5-6+7......+n的几种实现

    本文的内容本身来自一个名校计算机生的一次面试经历,呵呵,没错,你猜对了,肯定 不是我 个人很喜欢这两道题,可能题目原本不止两道,当然,我这里这分析我很喜欢的两道. 1.写一个函数计算当参数为n(n很大 ...

  8. 【SpringMVC】SpringMVC系列8之Servlet API 作为入参

    8.Servlet API 作为入参 8.1.概述 MVC 的 Handler 方法可以接受哪些 ServletAPI 类型的参数: HttpServletRequest HttpServletRes ...

  9. Burst Balloons

    Given n balloons, indexed from 0 to n-1. Each balloon is painted with a number on it represented by ...

  10. Power of Two & Power of Three & Power of Four

     Check Power of 2 Using O(1) time to check whether an integer n is a power of 2. Example For n=4, re ...