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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

Walker

發布時間:2023/12/3 编程问答 31 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Walker 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

Walker

題意:

一個區間[0,n],區間上有兩個點,坐標分別是pos1,pos2,速度分別是v1,v2,這兩個點是在移動,可以隨時改變移動方向,問當區間的每一塊均被一個點或兩個點移動覆蓋時,最少花費的時間是多少

題解:

介紹一個函數get_dis(pos,v,n):在pos位置覆蓋區間n需要的最短時間
這個最短時間由兩個部分取最小值
一個部分是從pos走到0再返回到n
另一個是從pos走到n再返回到0
我們分類討論情況:

  • 當其中一點的速度>>另一點速度時,這樣我們就靠一個點來跑完全程就行
  • ans = min(ans , get_dis(p1,v1,n));ans = min(ans , get_dis(p2,v2,n));
  • 當兩個點一開始重合時,這樣可以分別往兩邊跑,取兩者時間最大值
  • ans = min(ans , max((n-p1)/v1 , p2/v2));
  • 兩者相中間跑匯合后再反方向想往跑
    我們著重講第三點,這個匯合點pos怎么確定?
    我們先想想,在第三個情況下,兩者我們時間是要先取最大值,然后在最大值里選最小值,也就是兩者所用時間應該越相近越好,這樣可以保證最大化的最小值合理,而確定pos我們當然要用二分
    當前的mid使得前者時間大于后者時,mid就應該往左移動,所以r=mid,反之l=mid,進行個100多次二分,這個答案就會非常精確了
    以上三種情況取最小輸出
  • 代碼:

    #include <bits/stdc++.h> using namespace std;//在pos位置覆蓋到區間n需要的最短時間 double get_dis(double pos,double v,double n) { double a = (pos + n) / v; // 往左走到l再走到n double b = (n - pos + n) / v; //往右走到r再走到n return min(a,b); // 取最小值 }void Solve() {double n,p1,v1,p2,v2;scanf("%lf%lf%lf%lf%lf",&n,&p1,&v1,&p2,&v2);if(p1 > p2){swap(p1,p2);swap(v1,v2);}double ans = 9999999999999999;// 1.自己走完全程用的時間 ans = min(ans , get_dis(p1,v1,n));ans = min(ans , get_dis(p2,v2,n));// 2.相對走完自己的路程 ans = min(ans , max((n-p1)/v1 , p2/v2));// cout<<ans<<endl;double l = p1,r = p2; // 在p1和p2之間尋找一個分界點 for(int i=1;i<=100;i++) // 二分分界點 {double mid = (l + r) / 2; //分界點 double ans1 = get_dis(p1,v1,mid); double ans2 = get_dis(n-p2,v2,n-mid);ans = min(ans,max(ans1,ans2));if(ans1 < ans2) l = mid; // 讓到達分界點的時間盡可能的相同 else r = mid;}printf("%.12f",ans); } int main() {int t;scanf("%d",&t);while(t--){Solve();if(t) puts("");} }/* 2 10000.0 1.0 0.001 9999.0 0.001 4306.063 4079.874 0.607 1033.423 0.847 */

    總結

    以上是生活随笔為你收集整理的Walker的全部內容,希望文章能夠幫你解決所遇到的問題。

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