Created
June 3, 2016 16:59
-
-
Save macrat/57bc92ec6314f259ea505c46fa7c5859 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #include <algorithm> | |
| #include <iostream> | |
| #include <iterator> | |
| #include <set> | |
| #include <vector> | |
| class Position { | |
| private: | |
| int x, y; | |
| public: | |
| Position(int x, int y) : x(x), y(y) { } | |
| Position(const Position& m) : x(m.x), y(m.y) { } | |
| Position() : x(0), y(0) { } | |
| Position operator +(const Position p) const { | |
| return Position(x + p.x, y + p.y); | |
| } | |
| Position operator =(const Position& p) { | |
| x = p.x; | |
| y = p.y; | |
| return *this; | |
| } | |
| int getX() const { | |
| return x; | |
| } | |
| int getY() const { | |
| return y; | |
| } | |
| bool operator ==(const Position& p) const { | |
| return x == p.x && y == p.y; | |
| } | |
| bool operator !=(const Position& p) const { | |
| return !(*this == p); | |
| } | |
| bool operator <(const Position& p) const { | |
| return x < p.x || y < p.y; | |
| } | |
| }; | |
| class Map { | |
| private: | |
| std::vector< std::vector<bool> > data; | |
| public: | |
| const int w, h, level; | |
| Position start, goal; | |
| private: | |
| std::pair<Position, bool> find(const Position shift) const { | |
| if(!is_valid(start + shift) || !get(start + shift)){ | |
| return {start, false}; | |
| } | |
| Position cur(start); | |
| while(is_valid(cur + shift) && get(cur + shift) && cur != goal){ | |
| cur = cur + shift; | |
| } | |
| return {cur, true}; | |
| } | |
| public: | |
| Map(const int w, const int h) : w(w), h(h), level(1) { | |
| for(int x=0; x<w; x++){ | |
| data.push_back(std::vector<bool>(h)); | |
| } | |
| } | |
| Map(const Map& m) : w(m.w), h(m.h), level(m.level + 1), start(m.start), goal(m.goal) { | |
| std::copy(m.data.begin(), m.data.end(), std::back_inserter(data)); | |
| } | |
| static Map* read(const int w, const int h) { | |
| Map* map = new Map(w, h); | |
| for(int y=0; y<h; y++){ | |
| for(int x=0; x<w; x++){ | |
| int t; | |
| std::cin >> t; | |
| switch(t){ | |
| case 2: | |
| map->start = Position(x, y); | |
| break; | |
| case 3: | |
| map->goal = Position(x, y); | |
| break; | |
| } | |
| map->set(Position(x, y), t!=1); | |
| } | |
| } | |
| return map; | |
| } | |
| bool is_valid(const Position pos) const { | |
| return 0 <= pos.getX() && pos.getX() < w && 0 <= pos.getY() && pos.getY() < h; | |
| } | |
| bool get(const Position pos) const { | |
| return is_valid(pos) && data[pos.getX()][pos.getY()]; | |
| } | |
| void set(const Position pos, bool value) { | |
| if(is_valid(pos)){ | |
| data[pos.getX()][pos.getY()] = value; | |
| } | |
| } | |
| template <class T> int search(T& stack) const { | |
| if(level > 10){ | |
| return -1; | |
| } | |
| const Position shifts[] = {{1, 0}, {0, 1}, {0, -1}, {-1, 0}}; | |
| for(int i=0; i<4; i++){ | |
| const auto result = find(shifts[i]); | |
| if(result.first == goal){ | |
| return level; | |
| } | |
| if(result.second){ | |
| Map* next = new Map(*this); | |
| next->start = result.first; | |
| next->set(result.first + shifts[i], true); | |
| stack.insert(next); | |
| } | |
| } | |
| return -1; | |
| } | |
| }; | |
| struct map_compare { | |
| bool operator() (const Map* x, const Map* y) const { | |
| if(x->level != y->level) | |
| return x->level < y->level; | |
| return x->start < y->start; | |
| } | |
| }; | |
| int main() { | |
| while(true){ | |
| int w, h; | |
| std::cin >> w >> h; | |
| if(w == 0) | |
| break; | |
| std::set<Map*, map_compare> maps; | |
| maps.insert(Map::read(w, h)); | |
| int r; | |
| for(auto itr=maps.begin(); itr!=maps.end(); ++itr){ | |
| if((r = (*itr)->search(maps)) > 0){ | |
| break; | |
| } | |
| } | |
| std::cout << r << std::endl; | |
| for(auto itr=maps.begin(); !maps.empty();){ | |
| delete *itr; | |
| itr = maps.erase(itr); | |
| } | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment