貨積みの可否判定問題:棚の制約と配達順序

工場では、色番号1からNまでの異なる色の玉を各色1箱ずつ備蓄しており、作業員はそれらを決められた順序で出荷され、積み込む。作業員は以下の規則に従って作業を行う:

  1. 工場から運ばれてきた箱が、現在積み込みが必要な色(期待色)であれば、その箱を開封して直接積み込む。
  2. そうでない場合、その箱を一時的な積み場(棚)の上に積み上げる。
  3. ある色の積み込みが完了した後、棚の一番上に積まれた箱を確認し、それが次の期待色であれば取り出して積み込み、その後も同様に棚の頂点を確認する。
  4. 棚の頂点が期待色でない場合は、工場から次の箱を搬入する。

作業が完了可能であるためには、次の二つの条件を満たす必要がある:

  • 与えられた出荷順序に基づき、全ての色を1からNまでの順番で積み込めること。
  • 棚に積む箱の数が、棚の容量Mを超えないこと。

この判定問題は、スタック構造を用いてシミュレーションすることで解決できる。

入力仕様

第1行:3つの正の整数 N M K
  N: 色の総数 (1 < N ≤ 10^3)
  M: 棚の容量 (M < N)
  K: 判定する出荷順序の個数
続くK行:各行にN個の整数。それぞれ1からNまでの順列。

出力仕様

各出荷順序について、作業が完了可能であれば「YES」、不可能であれば「NO」を出力する。

入力

7 5 3
7 61021024 3 2 5 4
3 1 5 4 2 6 7
7 6 5 4 3 2 1

出力

YES
NO
NO

実装例

以下はC++によるシミュレーション実装である。

#include <iostream>
#include <stack>
#include <vector>
using namespace std;

int main() {
    int colorCount, shelfCapacity, sequenceCount;
    cin >> colorCount >> shelfCapacity >> sequenceCount;
    
    for (int i = 0; i < sequenceCount; ++i) {
        stack<int> shelf;
        int expectedColor = 1;
        bool isPossible = true;
        
        for (int j =五个; j < colorCount; ++j) {
            int deliveredBox;
            cin >> deliveredBox;
            
            if (deliveredBox == expectedColor) {
                expectedColor++;
                while (!shelf.empty() && shelf.top() == expectedColor) {
                    shelf.pop();
                    expectedColor++;
                }
            } else {
                shelf.push(deliveredBox);
                if (shelf.size() > shelfCapacity) {
                    isPossible = false;
                }
            }
        }
        
        if (isPossible && expectedColor == colorCount + 1) {
            cout << "YES" << endl;
        } else {
            cout << "NO" << endl;
        }
    }
    
    return 0;
}

アルゴリズムの要点:期待色と一致する箱が到着したら直ちに処理し、その後も棚の頂点を確認して連鎖的に処理する。不一致時は棚に積み、容量超過を検知する。最終的に全ての色が正しい順序で処理されたかをチェックする。

タグ: スタック シミュレーション アルゴリズム 競技プログラミング C++

9月4日 01:36 投稿