Official

A - 本棚の整理 / Organizing the Bookshelf Editorial by MMNMM


初心者の方へ

この問題は、for 文などを使って入力を読み込み、次の段に行くかを if 文などを使って正しく判定することで解くことができます。

以下のような工夫によって、管理すべきものを減らしたり実装・考察を楽にすることができます(もちろん、このような工夫をしなくてもこの問題を解くことができます)。

  • すでに配置を終えた段がどれだけ使われたかの情報は、これからの作業に関係ありません。よって、現在注目している段のうちどれだけの幅を使っているかのみ管理すればよいです。
  • すべての本の幅を \(1\) センチメートルだけ伸ばし、隙間を空けないことを考えます。すると、本来の置き方と比較して端に \(1\) センチメートルだけ余分が生じますが、これは本棚の横幅も同様に \(1\) センチメートル伸ばすことで配置できるかできないかを判定できるようになります。

実装例は以下のようになります。

#include <iostream>
using namespace std;

int main() {
    int N, W;
    cin >> N >> W;
    ++W; // 本棚の横幅を伸ばしておく

    int ans = 1; // 現在何段目か
    int now = 0; // 現在の段をどれくらい使ったか
    for (int i = 0; i < N; ++i) {
        int L;
        cin >> L;
        ++L; // 本の横幅も伸ばす
        if (now + L > W) { // 入らなければ
            ++ans; // 次の段に進み
            now = L; // その段の幅を L だけ使う
        } else { // 入るなら
            now += L; // 今の段を L だけ使う
        }
    }

    cout << ans << endl;
    return 0;
}
N, W = map(int, input().split())
W += 1 # 本棚の横幅を伸ばしておく

ans = 1 # 現在何段目か
now = 0 # 現在の段をどれくらい使ったか

for L in map(int, input().split()):
    L += 1 # 本の横幅も伸ばす
    if now + L > W: # 入らなければ
        ans += 1 # 次の段に進み
        now = L # その段の幅を L だけ使う
    else: # 入るなら
        now += L # 今の段を L だけ使う

print(ans)

posted:
last update: