TopCoder SRM 373 Div1 Medium RoadCrossing
問題
n人の通行人が、幅roadWidthの道路を横断する。
それぞれの通行人について、到着時刻および、横断速度が与えられる。
車がcarArrivalの時刻に道路にやってくる。
車は、通行人の隙間の最も大きい部分がcarWidthになると道路を通過できる。
車が通過できるようになる最初の時刻を求めよ。
制約条件
到着時刻≦1000
横断速度≦1000
carWidth,roadWidth≦1000
carArrival≦1000
方針
通行人同士の隙間がcarWidthになる時刻、および、
通行人と道路の端の隙間がcarWidthになる瞬間を全列挙する。
それぞれの瞬間において、車が通れるかどうかを見て、
車が通れる最も最初の瞬間を答えればよい。
ソースコード
class RoadCrossing { public: double passTime(vector <string> pedestrians, int roadWidth, int carWidth, int carArrival) { int n=pedestrians.size(); vector<pi> v; rep(i,n){ stringstream ss(pedestrians[i]); int a,b; ss>>a>>b; v.pb(mp(a,b)); } vd times; times.pb(carArrival); rep(i,n){ times.pb(carWidth*1.0/v[i].second+v[i].first); times.pb((roadWidth-carWidth)*1.0/v[i].second+v[i].first); } rep(i,n)rep(j,i){ if(v[j].second==v[i].second)continue; double a=v[i].first*v[i].second-v[j].first*v[j].second; double b=v[i].second-v[j].second; times.pb((a+carWidth)/b); times.pb((a-carWidth)/b); } sort(all(times)); rep(i,times.size())if(times[i]+EPS>carArrival){ vd pos; rep(j,n){ double p=v[j].second*(times[i]-v[j].first); if(0<p&&p<roadWidth)pos.pb(p); } pos.pb(0); pos.pb(roadWidth); sort(all(pos)); double mx=0; rep(j,(int)pos.size()-1)mx=max(mx,pos[j+1]-pos[j]); if(mx+EPS>carWidth)return times[i]; } return -1; } };