题目见:http://code.google.com/codejam/contest/32003/dashboard#s=p1
思路:
根据迷宫的行走路径倒推迷宫的结构。首先确定保存迷宫的数据结构。用普通的数组是不合适的,因为不知道迷宫的大小,也不知道迷宫入口的坐标。好在题目已经给定入口处在北方,所以迷宫只可能向三个方向延展。南北方向只要能够实现向容器后插入元素即可,东西方向需要能够方便的在容器前后都插入。同时还需要方便的按索引访问。这样比较合适的容器就只有std::deque了。每移动到一个新的坐标,就按照移动方向标记前一个坐标的出口和当前坐标的入口。最后再输出整个迷宫的信息。
题解:
#include <iostream> #include <fstream> #include <vector> #include <string> #include <map> #include <deque> #include <unordered_map> using namespace std; class Maze { enum { NORTH = (1<<0), SOUTH = (1<<1), WEST = (1<<2), EAST = (1<<3) }; const string SPOT_STATUS = "0123456789abcdef"; const unordered_map<int, int> TurnRight {{ {NORTH, EAST}, {SOUTH, WEST}, {EAST, SOUTH}, {WEST, NORTH} } }; const unordered_map<int, int> TurnLeft {{ {NORTH, WEST}, {SOUTH, EAST}, {EAST, NORTH}, {WEST, SOUTH} } }; const unordered_map<int, int> FlipMove {{ {NORTH, SOUTH}, {SOUTH, NORTH}, {EAST, WEST}, {WEST, EAST} } }; const unordered_map<int, pair<int, int>> MoveForward {{ {NORTH, {-1, 0}}, {SOUTH, {1, 0}}, {WEST, {0, -1}}, {EAST, {0, 1}} } }; int CurrentDirection; int MaxR, MaxC; int CurR, CurC; deque<deque<int>> Grid; void MoveAndExtend() { if (CurR < 0) { // this should not happen // since we always enter the maze at north side // neglect this section } else if (CurR >= MaxR) { ++MaxR; Grid.emplace_back (deque<int> (MaxC, 0)); } else if (CurC < 0) { ++CurC; ++MaxC; for (auto& r : Grid) r.push_front (0); CurC = 0; } else if (CurC >= MaxC) { ++MaxC; for (auto& r : Grid) r.push_back (0); } Grid[CurR][CurC] |= FlipMove.at (CurrentDirection); } void Visit (const string& v) { for (auto& ch : v) { switch (ch) { case 'W': Grid[CurR][CurC] |= CurrentDirection; CurR += MoveForward.at (CurrentDirection).first; CurC += MoveForward.at (CurrentDirection).second; MoveAndExtend(); break; case 'R': CurrentDirection = TurnRight.at (CurrentDirection); break; case 'L': CurrentDirection = TurnLeft.at (CurrentDirection); break; } } } public: void BidirectionTraverse (const string& forward, const string& backward) { MaxR = MaxC = 1; CurC = 0; CurR = 0; // we enter from outside of the maze Grid.push_back (deque<int> (1, 0)); CurrentDirection = SOUTH; // Give the entrance "CAN WALK NORTH" attribute Grid[0][0] |= NORTH; // we neglect the first move-in and last move-out instruction Visit (forward.substr (1, forward.size()-2)); Grid[CurR][CurC] |= CurrentDirection; CurrentDirection = FlipMove.at (CurrentDirection); Visit (backward.substr (1, backward.size()-2)); } void Print() { for (auto& c1 : Grid) { for (auto& c2 : c1) cout<<SPOT_STATUS[c2]; cout<<endl; } } }; int main (int argc, char* argv[]) { int num_sample; cin>>num_sample; vector<Maze> m; for (int i = 0; i < num_sample; ++i) { string enter, exit; cin>>enter>>exit; m.push_back (Maze()); m.back().BidirectionTraverse (enter, exit); } for (int i = 0; i < num_sample; ++i) { cout<<"Case #"<<i+1<<":"<<endl; m[i].Print(); } return 0; }