이 제출은 이전 버전의 oj.uz에서 채점하였습니다. 현재는 제출 당시와는 다른 서버에서 채점을 하기 때문에, 다시 제출하면 결과가 달라질 수도 있습니다.
#include <bits/stdc++.h>
using namespace std;
#include "robot.h"
enum State {
	BOUNDARY	= -2,
	OBSTACLE	= -1,
	EMPTY		= 0,
	MAIN		= 1,
	WEST		= 2,
	SOUTH		= 3,
	EAST		= 4,
	NORTH		= 5,
	
	BFS			= 6,
	RESOLVE		= 7,
	EVERYTHING	= -42,
	BLOCKED		= -3,
	DIRECTIONS	= -4,
	KEEP		= -5,
};
enum Move {
	M_STAY		= 'H',
	M_WEST		= 'W',
	M_SOUTH		= 'S',
	M_EAST		= 'E',
	M_NORTH		= 'N',
	M_TERMINATE	= 'T',
};
State clockwise(State S){
	if (S == NORTH) return EAST;
	if (S == EAST) return SOUTH;
	if (S == SOUTH) return WEST;
	if (S == WEST) return NORTH;
	return S;
}
State opposite(State S){
	return clockwise(clockwise(S));
}
State counter_clockwise(State S){
	return clockwise(opposite(S));
}
inline int idx(State S){
	assert(S >= 2 && S <= 5);
	return S - 1;
}
Move dirmove(State S){
	if (S == WEST) return M_WEST;
	if (S == SOUTH) return M_SOUTH;
	if (S == EAST) return M_EAST;
	if (S == NORTH) return M_NORTH;
	assert((false));
}
template <class T>
vector<T> operator + (const vector<T> &A, const vector<T> &B){
	vector<T> res = A;
	res.insert(res.end(), B.begin(), B.end());
	return res;
}
vector<State> expand(State S){
	if (S == BLOCKED) return {BOUNDARY, OBSTACLE};
	if (S == DIRECTIONS) return {WEST, SOUTH, EAST, NORTH};
	if (S == EVERYTHING){
		return expand(BLOCKED) + expand(DIRECTIONS)
		+ vector{EMPTY, MAIN, BFS, RESOLVE};
	}
	return {S};
}
namespace Script {
	static const int arrLen = 5;
	using StateArray = array<State, arrLen>;
	using Instruction = pair<State, Move>;
	StateArray everything(){
		StateArray res;
		for (int i = 0; i < arrLen; i++) res[i] = EVERYTHING;
		return res;
	}
	map<StateArray, Instruction> mp;
	template <bool OVERWRITE = false>
	void program(vector<vector<State>> S, Instruction _I){
		for (auto s0: S[0]) for (auto s1: S[1]) for (auto s2: S[2])
		for (auto s3: S[3]) for (auto s4: S[4]) {
			StateArray arr = {s0, s1, s2, s3, s4};
			if (!OVERWRITE && mp.count(arr)) continue;
			Instruction I = {_I.first == KEEP ? arr[0] : _I.first, _I.second};
			mp[arr] = I;
		}
	}
	template <bool OVERWRITE = false>
	void program(StateArray S, Instruction I){
		vector<vector<State>> expanded(arrLen);
		for (int i = 0; i < arrLen; i++){
			expanded[i] = expand(S[i]);
		}
		program<OVERWRITE>(expanded, I);
	}
	void set_all_instruction(){
		for (auto [S, I]: mp){
			vector<int> vS(begin(S), begin(S) + arrLen);
			set_instruction(vS, I.first, I.second);
		}
	}
}
void program_pulibot(){
	// Rule 1: Start at BFS
	{
		auto arr = Script::everything();
		arr[0] = EMPTY;
		arr[idx(WEST)] = BOUNDARY;
		arr[idx(NORTH)] = BOUNDARY;
		Script::program(arr, {BFS, M_STAY});
	}
	// Rule 2: Pull empty squares
	// Subrule 2.1: If we can pull, move to empty square
	for (State d: expand(DIRECTIONS)){
		auto arr = Script::everything();
		arr[0] = RESOLVE;
		arr[idx(d)] = EMPTY;
		Script::program(arr, {RESOLVE, dirmove(d)});
	}
	
	// Subrule 2.2: Return to old RESOLVE square
	for (State d: expand(DIRECTIONS)){
		auto arr = Script::everything();
		arr[0] = EMPTY;
		arr[idx(d)] = RESOLVE;
		Script::program(arr, {d, dirmove(d)});
	}
	// Subrule 2.3: If we cannot pull anymore, change to EMPTY
	// Moved below for ordering with Subrule 5.1
	// Rule 3: BFS
	// Subrule 3.1: If we can move to child square, move to it
	for (State d: expand(DIRECTIONS)){
		auto arr = Script::everything();
		arr[0] = BFS;
		arr[idx(d)] = opposite(d);
		Script::program(arr, {BFS, dirmove(d)});
	}
	// Subrule 3.2: If this points to a BFS square, change to BFS
	for (State d: expand(DIRECTIONS)){
		auto arr = Script::everything();
		arr[0] = d;
		arr[idx(d)] = BFS;
		Script::program(arr, {BFS, M_STAY});
	}
	// Subrule 3.3: If we cannot move anymore, change to RESOLVE
	{
		auto arr = Script::everything();
		arr[0] = BFS;
		Script::program(arr, {RESOLVE, M_STAY});
	}
	// Subrule 3.4: If empty and next to BFS, move
	for (State d: expand(DIRECTIONS)){
		auto arr = Script::everything();
		arr[0] = EMPTY;
		arr[idx(d)] = BFS;
		Script::program(arr, {EMPTY, dirmove(d)});
	}
	// Rule 4: Mark (H-1, W-1) as MAIN
	for (State d: expand(DIRECTIONS)){
		auto arr = Script::everything();
		arr[0] = EMPTY;
		arr[idx(d)] = RESOLVE;
		if (d == SOUTH || d == EAST) continue;
		arr[idx(SOUTH)] = BOUNDARY;
		arr[idx(EAST)] = BOUNDARY;
		Script::program<true>(arr, {MAIN, dirmove(d)});
	}
	// Rule 5: Cleanup
	// Subrule 5.1: If at RESOLVE, cannot move but next to MAIN, change to MAIN
	for (State d: expand(DIRECTIONS)){
		auto arr = Script::everything();
		arr[0] = RESOLVE;
		arr[idx(d)] = MAIN;
		Script::program(arr, {MAIN, M_STAY});
	}
	// Subrule 5.2: If at BFS and next to MAIN, change to RESOLVE
	for (State d: expand(DIRECTIONS)){
		auto arr = Script::everything();
		arr[0] = BFS;
		arr[idx(d)] = MAIN;
		Script::program<true>(arr, {RESOLVE, M_STAY});
	}
	// Subrule 5.2: If at MAIN or DIRECTIONS and can move to child square, move
	for (State d: expand(DIRECTIONS)){
		auto arr = Script::everything();
		arr[idx(d)] = opposite(d);
		arr[0] = MAIN;
		Script::program(arr, {KEEP, dirmove(d)});
		arr[0] = DIRECTIONS;
		Script::program(arr, {KEEP, dirmove(d)});
	}
	// Subrule 5.3: If at DIRECTIONS and cannot move, mark EMPTY and return
	for (State d: expand(DIRECTIONS)){
		auto arr = Script::everything();
		arr[0] = d;
		Script::program(arr, {EMPTY, dirmove(d)});
	}
	// Subrule 5.4: If at MAIN and cannot move to child square, move to BFS
	for (State d: expand(DIRECTIONS)){
		auto arr = Script::everything();
		arr[0] = MAIN;
		arr[idx(d)] = BFS;
		Script::program(arr, {MAIN, dirmove(d)});
	}
	// Subrule 2.3: If we cannot pull anymore, change to EMPTY
	{
		auto arr = Script::everything();
		arr[0] = RESOLVE;
		Script::program(arr, {EMPTY, M_STAY});
	}
	// Rule 6: Termination
	{
		auto arr = Script::everything();
		Script::program(arr, {MAIN, M_TERMINATE});
	}
	Script::set_all_instruction();
}
| # | Verdict | Execution time | Memory | Grader output | 
|---|
| Fetching results... | 
| # | Verdict | Execution time | Memory | Grader output | 
|---|
| Fetching results... | 
| # | Verdict | Execution time | Memory | Grader output | 
|---|
| Fetching results... | 
| # | Verdict | Execution time | Memory | Grader output | 
|---|
| Fetching results... | 
| # | Verdict | Execution time | Memory | Grader output | 
|---|
| Fetching results... | 
| # | Verdict | Execution time | Memory | Grader output | 
|---|
| Fetching results... |