1297-Swimming Jam
問題概要
往路と復路のあるプールがある.
往路と復路ともに非常に狭く追い抜きは出来ない.
ただし,一旦プールから出るときに,同時に出た人の仲で速い人が前になるように順番が調整される.
各個人の速度と往復回数が与えられるので,全員が泳ぎ終わるまでにかかる時間を求めよ.
解法
あるレーンで新規に泳ぐ人が泳ぎ終わるまでの時間は現在の時間をt,そのレーンで一番後ろにいる人が泳ぎ終わる時間をT,泳ぐ人の速度をvとすると
Max(T,t+v)となる.
後はqueueかdequeでシミュレーションするだけ.
実装(C++)
#include <iostream> #include <algorithm> #include <queue> #include <vector> #include <deque> using namespace std; typedef pair<int,int> P; #define REP(i,x) for(int i=0;i<(int)(x);i++) #define MAX(i,x) i=max(i,x); #define until(q) while(!(q)) P p[50];int n; int main(){ while(cin>>n,n){ REP(i,n){ cin>>p[i].first>>p[i].second; } std::sort(p,p+n); deque<P> swim[2]; int maxtime[2]={0,0}; REP(i,n){ swim[0].push_back(P(p[i].first,i)); MAX(maxtime[0],p[i].first); } int now=0; for(now=0;now<10000000;now++){ //レーン1で泳ぎ終わった人は居るか vector<int> tmp; while(swim[0].empty()==false&&swim[0].front().first==now){ tmp.push_back(swim[0].front().second); swim[0].pop_front(); } std::sort(tmp.begin(),tmp.end()); REP(i,tmp.size()){ MAX(maxtime[1],p[tmp[i]].first+now); swim[1].push_back(P(maxtime[1],tmp[i])); } //レーン2で泳ぎ終わった人は居るか tmp.clear(); while(swim[1].empty()==false&&swim[1].front().first==now){ tmp.push_back(swim[1].front().second); swim[1].pop_front(); } std::sort(tmp.begin(),tmp.end()); REP(i,tmp.size()){ if(--p[tmp[i]].second==0)continue; MAX(maxtime[0],p[tmp[i]].first+now); swim[0].push_back(P(maxtime[0],tmp[i])); } } cout<<maxtime[1]<<endl; } return 0; }