工場では、色番号1からNまでの異なる色の玉を各色1箱ずつ備蓄しており、作業員はそれらを決められた順序で出荷され、積み込む。作業員は以下の規則に従って作業を行う:
- 工場から運ばれてきた箱が、現在積み込みが必要な色(期待色)であれば、その箱を開封して直接積み込む。
- そうでない場合、その箱を一時的な積み場(棚)の上に積み上げる。
- ある色の積み込みが完了した後、棚の一番上に積まれた箱を確認し、それが次の期待色であれば取り出して積み込み、その後も同様に棚の頂点を確認する。
- 棚の頂点が期待色でない場合は、工場から次の箱を搬入する。
作業が完了可能であるためには、次の二つの条件を満たす必要がある:
- 与えられた出荷順序に基づき、全ての色を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;
}
アルゴリズムの要点:期待色と一致する箱が到着したら直ちに処理し、その後も棚の頂点を確認して連鎖的に処理する。不一致時は棚に積み、容量超過を検知する。最終的に全ての色が正しい順序で処理されたかをチェックする。