Problem C - Hot Dog Proliferation

問題

数列 Vi(≧0) の値が部分的に与えられる.(与えられない部分は 0 としてよい).このうち, 2≧Vi となる部分について
(Vi-1,Vi,Vi+1)←(Vi-1+1,Vi−2,Vi+1+1)
という処理を繰り返し,全体が 0≦Vi≦1 となるようにする.この処理は最低何回行う必要があるか?

Small だけ

いくつか手で試していれば,特に処理の順序には関係ないことが分かるはず.
なので単純にシミュレートするのが楽.Largeだと時間とメモリに無理が出る.16TBとか必要になる.

#include <iostream>
#include <map>
using namespace std;
typedef pair<int, int> Vender;

int solve()
{
  int C;
  map<int,int> vender;
  cin >> C;
  for( int i = 0 ; i < C ; ++i ) {
    int P, V;
    cin >> P >> V;
    vender.insert(Vender(P, V));
  }

  int cnt = 0;
  for( bool cont = true ; cont ; ) {
    cont = false;
    map<int,int>::iterator it;
    for( it = vender.begin() ; it != vender.end() ; ++it ) {
      if( it->second == 1 ) continue;
      cont = true;
      ++cnt;
      int p = it->first, v = it->second;
      if( vender.find(p-1) != vender.end() ) vender[p-1]++;
      else vender.insert(Vender(p-1,1));
      if( vender.find(p+1) != vender.end() ) vender[p+1]++;
      else vender.insert(Vender(p+1,1));
      if( (vender[p] -= 2) == 0 ) vender.erase(it);
    }
  }
  return cnt;
}

int main(void)
{
  int T;
  cin >> T;
  for( int t = 1 ; t <= T ; ++t ) {
    cerr << "Case #" << t << "\n";
    cout << "Case #" << t << ": " << solve() << "\n";
  }
  return 0;
}