Problem 1297 : Swimming Jam

Problem C: Swimming Jam
http://rose.u-aizu.ac.jp/onlinejudge/ProblemSet/description.jsp?id=1297

  • 問題概要

泳ぐ速さの違う人が泳ぐ。前に遅い人がいるとつっかえる。
人の体の大きさは考えなくていい。
2つレーンがあって、一方通行で往復できるようになってる。
つっかえている人たちがはしっこまでいったら、反対方向に行くときは
泳ぐのが早い人から順に飛び込む。
全員が予定していた回数往復するまで、どれだけ時間がかかりますか??

  • 解法

書くだけ。
往路と復路にベクターをわけて、一番手前の人が到着していたら、
その人から連続して到着している人のベクターをつくって、速さでソート。
反対方面のベクターに後ろから詰める。

  • ソース
#include<iostream>
#include<string>
#include<algorithm>
#include<vector>
#include<map>
#include<set>
#include<cstdlib>
#include<cstdio>
#include<cmath>
#include<sstream>
#include<cassert>
#include<queue>
#include<stack>

#define REP(i,b,n) for(int i=b;i<n;i++)
#define rep(i,n)   REP(i,0,n)
#define ALL(C)     (C).begin(),(C).end()
#define pb         push_back
#define mp         make_pair
#define vint       vector<int>
#define FOR(it,o)  for(__typeof((o).begin()) it=(o).begin(); it!=(o).end(); ++it)
#define lli	    long long int
#define ld	    long double

using namespace std;

class Man{
public:
  int pace, left, plan, id;
  Man(){}
  bool start(){
    left = pace;
    plan--;
    if(plan < 0)return false;
    else return true;
  }
  void move(){
    left--;
  }
  bool reach(){
    return left <= 0;
  }
  bool operator<(const Man &m)const{
    return pace < m.pace;
  }
  bool operator==(const Man &m)const{
    return id == m.id;
  }
};


main(){
  int n;
  while(cin >> n){
    if(n == 0)break;
    vector<Man> Go, Come;
    rep(i, n){
      Man m;
      cin >> m.pace >> m.plan;
      m.plan *= 2;
      m.id = i;
      m.start();
      Go.push_back(m);
    }
    sort(ALL(Go));
    int cnt = 0;
    while(Go.size() + Come.size() != 0){
      cnt++;
      FOR(it, Go)(*it).move();
      FOR(it, Come)(*it).move();
      if(Go.size() > 0 && Go[0].reach()){
	vector<Man> nCome;
	while(Go[0].reach()){
	  Go[0].start();
	  nCome.pb(Go[0]);
	  Go.erase(Go.begin());
	}
	sort(ALL(nCome));
	FOR(it, nCome)Come.pb((*it));
      }
      if(Come.size() > 0 && Come[0].reach()){
	vector<Man> nGo;
	while(Come[0].reach()){
	  if(Come[0].start())nGo.pb(Come[0]);
	  Come.erase(Come.begin());
	}
	sort(ALL(nGo));
	FOR(it, nGo)Go.pb((*it));
      }
    }
    cout << cnt << endl;
  }
}

書くだけだけど、楽しかった。