このTopCoderの問題はこちらで見ることができる(要TopCoder登録 & 問題文は英語)。問題文について意訳で説明する。
あなたはレストランのサービス部門のマネージャである。夕方のコースでは、顧客のグループがやってきて、その人たちをテーブルに配置しなければならない。レストランのテーブルは異なった人数の客に対応するために、さまざまなサイズのテーブルを用意している。テーブルへの客の配置は次のような手順で行う。客が現れたとき、まだ客で埋まっていないテーブルの内、そのグループ以上の人数を収められる最小のテーブルを客のために確保する。もし適切なテーブルが複数あれば、その中から任意に一つ割り当てる。もし適切なテーブルが一つもない場合は、顧客は即座に踵を返してその日の夕方は二度と現れない。グループが食事を終え、離れるとき、テーブルは利用できるようになり、新しい顧客を配置することができるようになる。
あなたはこの方法でテーブルに客を割り当てたとき、何人の顧客に逃げられるか知りたい。テーブルのサイズはtable[]という整数型配列で、各要素は収容可能な人数を表す。グループの人数、グループの到着時刻、出発時刻はそれぞれgroupSizes[i]、arrivals[i]、departures[i]である。i番目の要素はすべてグループiに関する情報である。グループは到着時刻順に並べられており、どのグループも同時に来ることはないものとする。もし、あるグループの出発時刻と別のグループの到着時刻が一致した場合は、出発するグループのテーブルは利用可能になっているものとする。逃げられた顧客の総数を返すメソッドを作成せよ。
私の解答はこちら。
import java.util.Arrays;
public class RestaurantManager {
public int allocateTables(int[] tables, int[] groupSizes, int[] arrivals, int[] departures) {
Arrays.sort(tables);
boolean[] isOccupied = new boolean[tables.length];
// テーブルにいるグループの出発時刻。
// i番目の要素がテーブルiを表す。値0はそのテーブルに誰も座ってないことを意味する
int[] depTime = new int[tables.length];
int nTurnedAway = 0;
for( int i=0 ; i<arrivals.length ; i++ ){
for( int j=0 ; j<tables.length ; j++ ){ // 来た人の時刻により、埋まっていたテーブルを解放
if( arrivals[i] >= depTime[j] && depTime[j] > 0 ){
isOccupied[j] = false;
depTime[j] = 0;
}
}
boolean caught = false;
for( int j=0 ; j<tables.length ; j++ ){ // 空いているテーブルの探索
// 最初に見つかったところに顧客を割り当てる(事前にテーブルサイズでソートしておくのがキモ)
if( isOccupied[j] == false && tables[j] >= groupSizes[i] ){
isOccupied[j] = true;
depTime[j] = departures[i];
caught = true;
break;
}
}
if( caught == false ){
nTurnedAway += groupSizes[i];
}
}
return nTurnedAway;
}
}
得点は201.97/250、1回のsubmitでシステムテストクリア。中央値は約125点。テーブルを小さい順に並び替えておくことで、空いている必要最上限のテーブルサイズを探索するのが容易になります。

0 件のコメント:
コメントを投稿