日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

《训练指南》——8.5

發布時間:2024/6/21 编程问答 31 豆豆
生活随笔 收集整理的這篇文章主要介紹了 《训练指南》——8.5 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

? Uva 11796:

? 甲和乙兩條狗分別沿著一條折線奔跑。兩只狗的速度位置,但已知他們同時出發,同時到達,并且都是勻速奔跑。你的任務是求出甲和乙在奔跑過程中的最遠距離和最近距離之差。

?

? 分析:這里分析兩只狗在運動過程的距離問題,我們這里面臨如下兩個困難:

(1)??? 兩只狗都在動。

(2)??? 狗的運動路線是折線。

為了解決第一個問題,我們這里考慮物理當中的運動相對性,我們假設兩只狗當前走得都是直線(簡化模型),我們將一直狗視為靜止,做其運動方向所在向量的相反向量,將其和另一只狗的運動向量進行合成,那么合成后的向量路徑其實就能夠準確的表示兩只狗的相對位置,那么我們求解比較困難的兩個動點間距離的最大值最小值的問題就轉化成了頂點到確定線段距離的最大值或者最小值。

? ? ? ? ? ? ? ? ? ? ? ? ?

? 而針對第二個問題,我們只需要在模擬計算的過程中,將整個運動過程一一劃分成上文所給出的“簡化模型”即可。

??

? 那么現在我們要在代碼層面進行更為詳細的討論:

? 如何求解一個頂點到一條線段的最短距離(最長距離)呢?

? 最長距離很好理解,一定是這個頂點到線段的兩個端點連線的其中一個,這個就不必贅言,這里我們主要分析一下最短距離。

? 首先我們要將幾何中所有的情況羅列出來,這樣對應著我們才能夠進行代碼實現。

?

?

?

? 下面基于圖形我們進行簡單的代數運算。

?

? ?

? 需要注意的幾點是,這里的情況其實包含了P在A、B上的情況。從微積分的教材上,向量的叉乘得到的是向量,但是這里我們進行叉乘運算得到的是數字,因此上式叉乘外邊的“||”符號是絕對值的意思。

??簡單的參考代碼如下(未提交):

?

#include<iostream> #include<cmath> #include<cstdio> #include<algorithm> const double eps=1e-10;using namespace std;struct Point {double x;double y;Point(double x=0,double y=0):x(x),y(y){}void operator<<(Point &A) {cout<<A.x<<' '<<A.y<<endl;} };int dcmp(double x) {return (x>eps)-(x<-eps); }typedef Point Vector;Vector operator +(Vector A,Vector B) { return Vector(A.x+B.x,A.y+B.y);}Vector operator -(Vector A,Vector 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);}// ps cout ostream &operator<<(ostream & out,Point & P) { out<<P.x<<' '<<P.y<<endl; return out;}bool operator< (const Point &A,const Point &B) { return A.x<B.x||(A.x==B.x&&A.y<B.y); }bool operator== ( const Point &A,const Point &B) { return dcmp(A.x-B.x)==0&&dcmp(A.y-B.y)==0;}double Dot(Vector A,Vector B) {return A.x*B.x+A.y*B.y;}double Cross(Vector A,Vector B) {return A.x*B.y-B.x*A.y; }double Length(Vector A) { return sqrt(Dot(A, A));}double DistanceToSegment(Point P , Point A , Point B) {if(A == B) return Length(P-A);Vector v1 = B-A ;Vector v2 = P-A ;Vector 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); }Point read_point() {Point P;scanf("%lf%lf",&P.x,&P.y);return P; }double Max,Min;const int maxn=60;Point P[maxn],Q[maxn];void update(Point P,Point A,Point B) {Min=min(Min,DistanceToSegment(P, A,B));Max=max(Max,Length(P-A));Max=max(Max,Length(P-B));}int main() {int T;int A,B;cin>>T;for(int kase = 1;kase <= T;kase++){cin>>A>>B;for(int i=0;i<A;i++) P[i]=read_point();for(int i=0;i<B;i++) Q[i]=read_point();double LenA=0,LenB=0;for(int i=0;i<A-1;i++) LenA+=Length(P[i+1]-P[i]);for(int i=0;i<B-1;i++) LenB+=Length(Q[i+1]-Q[i]);int Sa=0,Sb=0;Min= 1e9;Max=-1e9;Point Pa=P[0];Point Pb=Q[0];while(Sa<A-1 && Sb < B-1){double La=Length(P[Sa+1]-Pa);double Lb=Length(Q[Sb+1]-Pb);double T=min(La/LenA,Lb/LenB);Vector Va=(P[Sa+1]-Pa)/La*T*LenA;Vector Vb=(Q[Sb+1]-Pb)/Lb*T*LenB;update(Pa,Pb,Pb+Vb-Va);Pa=Pa+Va;Pb=Pb+Vb;if(Pa==P[Sa+1]) Sa++;if(Pb==Q[Sb+1]) Sb++;}printf("Case %d: %.0lf\n",kase,Max -Min);}}

?

轉載于:https://www.cnblogs.com/rhythmic/p/5743156.html

總結

以上是生活随笔為你收集整理的《训练指南》——8.5的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。