【CodeForces - 701D】As Fast As Possible(二分)

題意:n個人,走一段l長的路,有一輛能裝k個人的車,人的速度v1,車的速度v2,v1<v2。人只能上一次車。問走完這段路的最短時間。

思路:二分時間,通過推一些列公來判斷是否可行。主要思想就是步行時間比當前枚舉的時間多d,則每個人都要減少d時間的耗費,所以假設車載x米能使得k個人減少d的耗時。然後每個人都要上一次車,並且除最後一波人外,車方下人後都要返回。看看在走路的人到終點時,車能不能運着最後一波人到終點。

錯誤原因:

當二分上下界過小,ans又沒賦初始值,那麼可能不會給ans賦值就直接跳出了,所以儘量將二分的界限開的稍大一點,並且給ans賦值。二分精度不要太大,這道題1e-8就會超時。

ac代碼:

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<cstring>
#include<queue>
#include<stack>
#include<map>
#include<set>
#include<string>
#include<vector>
#include<unordered_map>
#define mod (1000000007)
using namespace std;
typedef long long ll;
const int maxn = 3e5 + 100;
const ll inf = 1e14;
const double eps=1e-7;//-8就T了,精度不要太大

int main() {
    ll n,l,v1,v2,num,k;
    cin>>n>>l>>v1>>v2>>k;
    double T=l*1.0/v1;
    double L=min(l*1.0/v2,0.25),R=T+10,ans;//ans賦初始值,或者將上下界調的寬一點,否則可能不能給ans賦值,直接跳出了
    num=(n+k-1)/k;
    while(R-L>eps){
        double mid=(L+R)/2;
        double dt=T-mid;
        double x=(dt*v1*v2)/(v2-v1);
        double t2=x/v2+(x-x*v1/v2)/(v1+v2);
        double ok=x/v2+(l-x)/v1-(num-1)*(t2)-(x/v2);
        if(ok>eps){
            ans=mid;
            R=mid;
        }
        else{
            L=mid;
        }
    }
    printf("%.6f\n",ans);
    return 0 ;
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章