公式

B - 会議室の空き時間 / Available Time Slots for Meeting Rooms 解説 by physics0523


俗に イベントソート と呼ばれる方法でこの問題を解くことができます。

時刻 \([S_i,E_i)\) の会議室の予約を以下のように言い換えます。

  • 時刻 \(S_i\) に予約が \(1\) 増える。
  • 時刻 \(E_i\) に予約が \(1\) 減る。

これを時刻の順にソートし、以下の処理を行います。

  • 現在の予約の数 \(h=0\) から始める。また、便宜上空き時間が時刻 \(0\) から開始しているとする。
  • \(h=0\) かつ予約が増えた結果 \(h>0\) となるなら、空き時間が終了する。
  • \(h>0\) かつ予約が減った結果 \(h=0\) となるなら、空き時間が開始する。
  • \(h\) に予約の数の変動を反映させ、次の時刻に進む。

この「空き時間の開始」「空き時間の終了」を検出すると、最長の連続する空き時間も求めることができます。

なお、時刻 \([T,\infty)\) に予約があるとして扱うと実装が少し楽になります。
本解法の時間計算量は \(O(N \log N)\) です。

実装例 (C++):

#include<bits/stdc++.h>

using namespace std;

int main(){
  int N,T;
  cin >> N >> T;
  map<int,int> mp;
  mp[T]++;
  for(int i=0;i<N;i++){
    int S,E;
    cin >> S >> E;
    mp[S]++;
    mp[E]--;
  }
  int res=0,h=0,pre=0;
  for(auto &nx : mp){
    if(h==0 && nx.second>0){
      res=max(res,nx.first-pre);
    }
    if(h>0 && h+nx.second==0){
      pre=nx.first;
    }
    h+=nx.second;
  }
  cout << res << "\n";
  return 0;
}

投稿日時:
最終更新: