今回は paiza の「長テーブルのうなぎ屋」の問題に挑戦!
🧩 問題概要
円形テーブル(座席1〜n番)に、m組のグループが順番に座りに来る。
各グループは「人数 a_i」と「開始座席 b_i」が指定され、
b_i から連続 a_i 個の席に座ろうとする。
ただし:
- その範囲に1つでもすでに人が座っている席がある場合 → そのグループは全員座らず帰る。
- そうでなければ → 全員が座る。
最終的に、実際に座れた人数の合計を出力する。
入力例:
6 3
3 2
1 6
2 5
出力例:
4
✅ OK例:
const rl = require('readline').createInterface({ input:process.stdin });
const lines = [];
// 入力を1行ずつ読み込み
rl.on('line', (input) => lines.push(input));
rl.on('close', () => {
const [n, m] = lines[0].split(' ').map(Number); // 座席数n、グループ数m
const groups = lines.slice(1).map(line => line.split(' ').map(Number)); // 各グループの[a, b]
const seats = Array(n).fill(0); // 座席の状態(0=空席, 1=使用中)
let ans = 0; // 着席できた人数の合計
for (let i = 0; i < m; i++) {
const [a, bRaw] = groups[i];
const b = bRaw - 1; // 1始まりを0始まりに変換
// b番目からa人分の席に既に人がいるかチェック
if (!seats.slice(b, a + b).includes(1)) {
// 全員座れる場合のみカウントを増やす
ans += a;
// 実際に席を1に変更
for (let j = b; j < a + b; j++) {
if (j < n) {
seats[j] = 1; // 通常範囲
} else {
seats[j - n] = 1; // テーブル末尾を超えた場合、先頭へ戻る
}
}
}
}
console.log(ans); // 着席できた合計人数を出力
});
📘 まとめ
- 問題の本質
→ 複数グループが順番に「座れるかどうか」をシミュレーションする。 - 入力処理
→ 1行目:n, m
→ 2行目以降:a_i, b_i(人数と開始位置) - 配列初期化
→Array(n).fill(0)で全席を空席にする。 - 座れるかの判定
→slice(b, b + a).includes(1)で既占有チェック。
→!includes(1)なら全員着席OK。 - 円形処理
→if (j >= n) seats[j - n] = 1;
→n番目を超えたら先頭に戻る。 - 人数カウント
→ 座れたグループの人数をans += a;で加算。