●UVA 11796 Dog Distance

题链:

https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=2896

题解:

计算几何,骚操作
对于简单情况,即两只狗的路线均为一条线段,
可以从相对运动的角度出发,考虑一直狗不动,另一只狗在运动。
而由于两只狗此时都在做匀速直线运动,所以在那只不懂的狗看来,另一直狗也在匀速直线前行。(物理老师:速度的矢量和!)
所以这个简单情况下,问题就变为了求一个点到一条线段的最短和最长距离。

而本题中虽然路线为多条折线,但仍然可以根据拐点把路线拆为一个个的简单情况,进而即可求解。

代码:

#include<cmath>
#include<cstdio>
#include<cstring>
#include<iostream>
#define MAXN 60
using namespace std;
const double eps=1e-8;
struct Point{
	double x,y;
	Point(double _x=0,double _y=0):x(_x),y(_y){}
	void Read(){scanf("%lf%lf",&x,&y);}
};
int sign(double x){
	if(fabs(x)<=eps) return 0;
	return x<0?-1:1;
}
typedef Point Vector;
bool operator == (Point A,Point B){return sign(A.x-B.x)==0&&sign(A.y-B.y)==0;}
Vector operator + (Vector A,Vector B){return Vector(A.x+B.x,A.y+B.y);}
Vector operator - (Point A,Point B){return Vector(A.x-B.x,A.y-B.y);}
Vector operator * (Vector A,double p){return Vector(A.x*p,A.y*p);}
Vector operator / (Vector A,double p){return Vector(A.x/p,A.y/p);}
double operator ^ (Vector A,Vector B){return A.x*B.y-A.y*B.x;}
double operator * (Vector A,Vector B){return A.x*B.x+A.y*B.y;}
Vector Va,Vb;
Point Da[MAXN],Db[MAXN],Pa,Pb;
int T,Na,Nb,ia,ib;
double minans,maxans,La,Lb,Lena,Lenb,tim;
double GL(Vector A){//Get_Length
	return sqrt(A*A);
}
double DTS(Point P,Point a1,Point a2){//Distance_To_Segment
	static Vector v1,v2,v3;
	v1=a2-a1; v2=P-a1; v3=P-a2;
	if(a1==a2) return GL(v2);
	if(sign(v1*v2)<0) return GL(v2);
	if(sign(v1*v3)>0) return GL(v3);
	return fabs(v2^v3)/GL(v1);
}
void contribution(Point P,Point a1,Point a2){
	minans=min(minans,DTS(P,a1,a2));
	maxans=max(maxans,GL(P-a1));
	maxans=max(maxans,GL(P-a2));
}
int main(){
	freopen("/home/noilinux/Documents/模块学习/计算几何/11796.in","r",stdin);
	scanf("%d",&T);
	for(int t=1;t<=T;t++){
		scanf("%d%d",&Na,&Nb);
		for(int i=1;i<=Na;i++) Da[i].Read();
		for(int i=1;i<=Nb;i++) Db[i].Read();
		Lena=Lenb=0; minans=1e9; maxans=-1e9;
		for(int i=1;i<Na;i++) Lena+=GL(Da[i+1]-Da[i]);
		for(int i=1;i<Nb;i++) Lenb+=GL(Db[i+1]-Db[i]);
		ia=1,ib=1; Pa=Da[1],Pb=Db[1];
		while(ia<Na&&ib<Nb){
			La=GL(Da[ia+1]-Pa);
			Lb=GL(Db[ib+1]-Pb);
			tim=min(La/Lena,Lb/Lenb);
			Va=(Da[ia+1]-Pa)/La*tim*Lena;
			Vb=(Db[ib+1]-Pb)/Lb*tim*Lenb;
			contribution(Pa,Pb,Pb+Vb-Va);
			Pa=Pa+Va; Pb=Pb+Vb;
			if(Pa==Da[ia+1]) ia++;
			if(Pb==Db[ib+1]) ib++;
		}
		printf("Case %d: %.0lf\n",t,maxans-minans);
	}
	return 0;
}

  

原文地址:https://www.cnblogs.com/zj75211/p/8227590.html

时间: 2024-11-10 00:54:13

●UVA 11796 Dog Distance的相关文章

uva 11796 Dog Distance (计算几何-点和直线)

C Dog Distance Input Standard Input Output Standard Output Two dogs, Ranga and Banga, are running randomly following two different paths. They both run for T seconds with different speeds. Ranga runs with a constant speed of R m/s, whereas Banga runs

相对运动模拟:UVa 11796 Dog Distance

11796 - Dog Distance 题目大意 甲和乙两条狗分别沿着给定的折线匀速奔跑,同时出发.同时到达,试计算甲和乙在奔跑过程中的最远距离和最近距离的差. 解题思路 模拟整个过程,把总过程分割成一个个子过程:甲和乙的路线都是一条线段,因为运动是相对的,因此也可以认为甲静止不动,乙自己沿着某个相对运动的直线(用相对位移向量表示)走,因此问题转化为点到线段的最小最大距离,注意子过程的最小最大值不代表整个过程的最小最大值,所以每处理完一个子过程就要不断更新. 假设现在甲的位置是Pa,刚经过编号

UVa 11796 Dog Distance

题意: 有甲乙两条狗分别沿着一条折线奔跑,已知它们同时从各自的起点出发,同时到达各自的终点.求整个过程中两条狗的最大距离Max与最小距离Min的差值. 分析: 假设甲乙的路线都是一条线段的简单情况.运动是相对的,我们假定甲不动,乙相对甲的运动也是匀速直线运动.所以就将问题转化成了点到直线的最小和最大距离. 甲或乙每到达一个拐点所对应的时刻称作“关键点”,那么没两个关键点之间的运动都可看做上面分析的简单情况.我们只要及时更新甲乙的位置即可. LenA和LenB分别是两条路线的总长,因为运动时间相同

UVA - 11796 - Dog Distance (计算几何~)

不得不感叹,计算几何真是太美丽了!! AC代码: #include <cstdio> #include <cstring> #include <algorithm> #include <iostream> #include <cmath> using namespace std; struct Point { double x, y; Point(double x = 0, double y = 0) : x(x) , y(y) { } }; t

简单几何(相对运动距离最值) UVA 11796 Dog Distance

题目传送门 题意:两只狗在折线上跑,速度未知,同时出发,同时达到.问跑的过程中,两狗的最大距离和最小距离的差 分析:训练指南P261,考虑相对运动,设A静止不动,B相对A运动,相对的运动向量:Vb - Va(可以理解为速度矢量),那么就是pa到线段pb-pb+Vb-Va的距离最值 /************************************************ * Author :Running_Time * Created Time :2015/10/22 星期四 10:21

【UVA】11796 - Dog Distance(相对运动)

因为a,b是同时出发,同时达到,但是他们的速度不一定一样,所以我们可以设他们的速度为La,Lb(La,Lb为a,b狗的总路程) 那么,如何a,b都是沿着直线运动的时候如何求他们之间的最短最长距离呢? 因为运动都是相对的,所以我们可以把a看成不懂的,而b相对于a的移动方向就是Vb - Va,因此就可以看成a和线段 b + (Vb -Va)之间的关系了 至于方向Va,Vb向量怎么求,我们可以利用单位向量 X 移动时间 X 移动速度 得到. 经典的一道题,顺便还修复了一个模板的BUG: 1412818

UVA 10140 - Prime Distance(数论)

10140 - Prime Distance 题目链接 题意:求[l,r]区间内最近和最远的素数对. 思路:素数打表,打到sqrt(Max)即可,然后利用大的表去筛素数,由于[l, r]最多100W,所以可以去遍历一遍,找出答案.注意1的情况,一开始没判断1,结果WA了 代码: #include <stdio.h> #include <string.h> #include <algorithm> using namespace std; #define INF 0x3f

UVA11796 Dog Distance 计算几何

计算几何: 题解转自:点击打开链接 首先我们想一下如果甲乙都仅沿着两条线段向前跑,那么他们之间的最短和最长距离怎么算? 假设甲的速度向量为v1(速度向量指甲单位时间所走的位移向量),乙的速度向量为v2. 那么可以把甲看成是静止不动的,而让乙一个人以v2-v1的速度向量去运动(画图验证下). 且假设甲和乙都运动了t秒时间,那么我们可以知道上面的过程类似于甲不动,乙从自己的起点运动了t*(v2-v1)的位移向量. 而乙已知起点和位移向量,那么它就是在一条线段上. 最终我们要求的就是甲这个不动的点到乙

UVA 11796

题意:  有两个狗, 按照 多边形跑,不知道两条狗的速度,但是狗是同时出发,同时到达终点的 输出两条狗的 最大相距距离 - 最小相距距离: 思路 : 用物理的相对运动来计算, 每次只计算 两条狗的直线运动, 转折点再额外更新 LRJ 模板大法好 !!!LRJ 模板大法好 !!!!LRJ 模板大法好 !!!! #include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #i