UVA 11796 || Dog Distance ( 折线划分线段更新
来源:互联网 发布:ubuntu 命令行解压deb 编辑:程序博客网 时间:2024/06/07 07:01
狗A,狗B,分别沿着两条折线奔跑,两只狗的速度未知。
已知:
两只狗同时出发,同时到达,并且都是匀速奔跑。
可以假设奔跑的总时长为 1s,这样两只狗的速度就等于折线的长度。速度就变成已知啦。
求:狗A , 狗B,在奔跑过程中最近距离,和最远距离的差。
这题感觉用到了DP的思想。
把这线段以拐点为划分,酱紫就得到了一条一条的线段。那么可以看做:
在某一时间内,两条狗都在线段上奔跑。
划分为子问题,就是每次解出这些线段。
由物理的相对运动知道。
假设狗A的速度为av,狗B的速度为bv,那么可以看做,狗A静止不动,狗B以(bv-av)的速度奔跑。
由此可以化简为点到直线的距离。
画图推一下就知道了,最大距离是一定在端点上的。
设立两个变量pa,pb,表示狗A,狗B当前出发的点。
sa+1,sb+1,就是目前这一线段的终点,看做子问题就是狗要跑到这里就好了。
算出先到达拐点的狗花费的时间。
再算出两只狗的位移。到达拐点的狗就更新当前点,以此 sx+1 拐点为下一次奔跑的起点。
另外一只狗以 sx+1 为终点,上一次花费 t 时间跑到的地方为起点。
如此循环更新 :)
具体--》
两条狗以 A,B 起点,狗A先到达拐点C,狗B此时到达D点。
那么更新最大值最小值。更新当前点。
狗A,下一次的起点为 C 点,终点 E。
狗B,下一次的起点为 D 点,终点..哦 我忘记画出来了!!自己懂!!
#include<iostream>#include<cstdio>#include<cmath>#include<algorithm>using namespace std;struct point{ double x,y,d; point(double a,double b):x(a),y(b){} point(){} void read() { scanf("%lf%lf",&x,&y);}};typedef point vec;vec operator + ( vec a, vec b) { return vec(a.x+b.x,a.y+b.y);}vec operator - ( point a, point b) { return vec(a.x-b.x,a.y-b.y);}vec operator * ( vec a, double p) { return vec(a.x*p,a.y*p);}vec operator / ( vec a, double p) { return vec(a.x/p,a.y/p);}double dot( vec a,vec b) { return a.x*b.x + a.y*b.y;}double length( vec a) { return sqrt( dot(a,a));}const int maxn = 50+5;int t,anum,bnum;point ap[maxn],bp[maxn];double mx,mi;double cross( vec a,vec b ){ return a.x*b.y - a.y*b.x;}const double eps =1e-6;int dcmp( double x){ if( fabs(x)<eps )return 0; return x < 0?-1:1;}bool operator == ( const point &a,const point &b){ return dcmp(a.x-b.x) == 0 && dcmp(a.y-b.y)==0;}double distosegment( point p,point a,point b){ if( a==b ) return length(p-a); vec v1 = b-a; vec v2 = p-a; vec v3 = p-b; if( dcmp( dot(v1,v2)) < 0 )return length(v2); else if( dcmp ( dot(v1,v3)) >0 )return length(v3); else return fabs( cross(v1,v2)/length(v1) );}void update(point p,point a,point b){ mi = min(mi,distosegment(p,a,b)); mx = max(mx,length(p-a)); mx = max(mx,length(p-b));}int main(){ cin>>t; for( int cas = 1;cas<=t;++cas) { cin>>anum>>bnum; double av=0.0,bv=0.0; ap[0].read(); for( int i = 1 ; i <anum;++i) { ap[i].read(); av += length(ap[i]-ap[i-1]); } bp[0].read(); for( int i = 1 ;i <bnum;++i) { bp[i].read(); bv += length(bp[i]-bp[i-1]); } int sa,sb; sa = sb = 0; point pa=ap[0],pb=bp[0];//当前点 mi = 1e9; mx = -1e9; while( sa<anum-1 && sb<bnum-1) { double alen = length( ap[sa+1]-pa);//当前点到下一拐点的距离 double blen = length( bp[sb+1]-pb); double t = min( alen/av,blen/bv); //当某一只狗率先到达拐点时,两只狗的位移 vec awalk = ( ap[ sa+1]-pa)/alen * t *av; vec bwalk = ( bp[ sb+1]-pb)/blen * t *bv; //更新当前最大值,最小值 再更新当前点 update( pa,pb,pb+bwalk-awalk); /* 狗A,狗B同时奔跑。 可以将狗A看做静止,狗B以 (bv - av)的速度奔跑。 */ pa = pa+awalk; pb = pb+bwalk; if( pa==ap[sa+1])sa++; if( pb==bp[sb+1])sb++; } printf("Case %d: %.0lf\n",cas,mx-mi); } return 0;}
0 0
- UVA 11796 || Dog Distance ( 折线划分线段更新
- UVA 11796 Dog Distance
- uva 11796 - Dog Distance
- UVA 11796 - Dog Distance
- UVA 11796Dog Distance
- UVA 11796 Dog Distance
- UVA 11796 Dog Distance
- UVA 11796 - Dog Distance
- UVA 11796 Dog Distance .
- UVA 11796 Dog Distance 几何
- Dog Distance - UVa 11796 几何
- uva 11796 - Dog Distance(投影位移)
- UVA 11796 - Dog Distance 向量的应用
- 【UVA】11796 - Dog Distance(相对运动)
- uva 11796 Dog Distance(计算几何, 基础)
- UVA 11796 Dog Distance(点与向量)
- UVA - 11796 - Dog Distance (计算几何~)
- 相对运动模拟:UVa 11796 Dog Distance
- 二月五号六号 集训第五第六天 线段树
- 正常显示,鼠标按下,鼠标弹起,按钮显示不同的图
- OC笔记 - 面向对象特性(2015.1.28)
- 关于求最大联通域的OpenCV方法
- Android C++层内存泄漏检测
- UVA 11796 || Dog Distance ( 折线划分线段更新
- A Good Bye 2014(CF)
- Android获取View的高宽
- cc150:判断一棵树是否为平衡树
- Android使用AttributeSet自定义控件的方法
- B. New Year Permutation (CF)
- OC笔记 - 手动内存管理的基本概念(2015.1.30)
- [LeetCode]78.Subsets
- poj 2240 Floyd判断有向图负环(arbitrage)