# Include <iostream> <br/> # include <list> <br/> # include <string> <br/> # include <tuple> <br/> # include <Algorithm> <br/> # include <boost/foreach. HPP> <br/> using namespace STD; </P> <p> typedef pair <int, int> position; </P> <p> inline position operator + (const Position & P1, const Position & p2) <br/>{< br/> return position (p1.first + p2.first, p1.second + p2.second); <br/>}</P> <p> inline unsigned int myabs (int I) <Br/>{< br/> return static_cast <unsigned int> (I <0? -I: I); <br/>}</P> <p> position offset [] ={< br/> position (0,-1 ), <br/> position (0, 1), <br/> position (-1, 0), <br/> position (1, 0), <br/> }; </P> <p> struct puz_game <br/>{< br/> position m_size; <br/> string m_start, m_goal; <br/> position m_space; </P> <p> puz_game (int r, int C, const string & START, const string & goal); <br/> int rows () const {return m_size.first ;} <br/> int Cols () const {return m_size.second ;}< Br/>}; </P> <p> puz_game: puz_game (int r, int C, const string & START, const string & goal) <br/>: m_size (R, c) <br/>, m_start (start) <br/>, m_goal (GOAL) <br/>{< br/> int n = m_start.find (''); <br/> m_space = position (N/Cols (), N % Cols ()); <br/>}</P> <p> struct puz_state: String <br/>{< br/> puz_state () {}< br/> puz_state (const puz_game & G) <br/>: string (G. m_start), m_game (& G), m_space (G. m_space), m _ Move (0) {}< br/> int rows () const {return m_game-> rows () ;}< br/> int Cols () const {return m_game-> Cols () ;}< br/> char cell (int r, int c) const {return at (R * Cols () + C );} <br/> char & cell (const Position & P) {return (* This) [p. first * Cols () + P. second] ;}< br/> bool is_valid (const Position & P) const {<br/> return p. first> = 0 & P. first <rows () & P. second> = 0 & P. second <Cols (); <br/>}< br/> void m Ake_move (const Position & P, char move) {<br/> cell (m_space) = cell (P); <br/> cell (m_space = P) = ''; <br/> m_move = move; <br/>}</P> <p> // puz_solver_idastar interface <br/> bool is_goal_state () const {return * This = m_game-> m_goal;} <br/> void gen_children (list <puz_state> & Children) const; <br/> unsigned int get_heuristic () const; <br/> unsigned int get_distance (const puz_state & Child) const {return 1 ;} </P> <p> const puz_game * m_game; <br/> position m_space; <br/> char m_move; <br/> }; </P> <p> void puz_state: gen_children (list <puz_state> & Children) const <br/>{< br/> char * moves = "wens "; <br/> for (INT I = 0; I <4; ++ I) {<br/> position P = m_space + offset [I]; <br/> If (is_valid (p) {<br/> children. push_back (* This); <br/> children. back (). make_move (p, moves [I]); <br/>}</P> <p> unsigned int puz_sta Te: get_heuristic () const <br/>{< br/> unsigned int MD = 0; <br/> for (size_t I = 0; I <size (); ++ I) {<br/> size_t J = m_game-> m_goal.find (at (I); <br/> MD + = myabs (J/Cols () -I/Cols () + myabs (J % Cols ()-I % Cols (); <br/>}< br/> return md; <br/>}</P> <p> ostream & operator <(ostream & out, const puz_state & S) <br/>{< br/> If (S. m_move) <br/> out <"Move:" <S. m_move <Endl; <br/> for (INT r = 0; R <S. rows (); ++ R) {<br/> for (int c = 0; C <S. cols (); ++ c) <br/> out <S. cell (R, c) <''; <br/> out <Endl; <br/>}< br/> return out; <br/>}</P> <p> template <class puz_state> <br/> class puz_solver_idastar <br/>{< br/> static bool DFS (unsigned int start_cost, const puz_state & cur, <br/> unsigned int cost_limit, unsigned Int & next_cost_limit, <br/> List <puz_state> & Spath, size_t & examined) <br/> {<br/> ++ E Xamined; <br/> unsigned int minimum_cost = start_cost + cur. get_heuristic (); <br/> If (minimum_cost> cost_limit) <br/> return next_cost_limit = min (next_cost_limit, minimum_cost), false; <br/> If (cur. is_goal_state () <br/> return next_cost_limit = cost_limit, true; </P> <p> List <puz_state> children; <br/> cur. gen_children (children); <br/> boost_foreach (const puz_state & Child, children) {<br/> // full cycle C Hecking <br/> If (find (Spath. Begin (), Spath. End (), Child )! = Spath. end () <br/> continue; <br/> unsigned int new_start_cost = start_cost + cur. get_distance (child); <br/> Spath. push_back (child); <br/> bool found = DFS (new_start_cost, child, cost_limit, next_cost_limit, Spath, examined); <br/> If (found) <br/> return true; <br/> Spath. pop_back (); <br/>}</P> <p> return false; <br/>}</P> <p> public: <br/> static pair <bool, size_t> find_solution (const puz_state & sstart, list <puz_state> & Spath) <br/>{< br/> unsigned int INF = numeric_limits <unsigned int >:: max (); <br/> unsigned int cost_limit = sstart. get_heuristic (), next_cost_limit = inf; <br/> size_t examined = 0; <br/> Spath. assign (1, sstart); <br/> for (;) {<br/> bool found = DFS (0, sstart, cost_limit, next_cost_limit, Spath, examined ); <br/> If (found) <br/> return make_pair (true, examined); <br/> If (next_cost_limit = inf) <br/> return make_pair (false, examined); <br/> cost_limit = next_cost_limit, next_cost_limit = inf; <br/>}< br/> }; </P> <p> int main () <br/> {<br/> // start state <br/> // 2 8 3 <br/> // 1 6 4 <br/> // 7 5 <br/> // goal state <br/> // 1 2 3 <br/> // 8 4 <br/> // 7 6 5 <br/> puz_game g (3, 3, "2831647 5", "1238 4765"); <br/> List <puz_state> Spath; </P> <p> bool found; <br/> size_t examined; <br/> tie (found, examined) = puz_solver_idastar <puz_state>: find_solution (G, Spath); <br/> If (found) {<br/> cout <"sequence of moves:" <Endl; <br/> boost_foreach (const puz_state & S, Spath) <br/> cout <s; <br/> cout <"number of moves:" <Spath. size ()-1 <Endl; <br/>}< br/> cout <"Number of States examined:" <examined <Endl; <br/>}</P> <p>/* <br/> sequence of moves: <br/> 2 8 3 <br/> 1 6 4 <br/> 7 5 <br/> move: n <br/> 2 8 3 <br/> 1 4 <br/> 7 6 5 <br/> move: n <br/> 2 3 <br/> 1 8 4 <br/> 7 6 5 <br/> move: W <br/> 2 3 <br/> 1 8 4 <br/> 7 6 5 <br/> move: S <br/> 1 2 3 <br/> 8 4 <br/> 7 6 5 <br/> move: E <br/> 1 2 3 <br/> 8 4 <br/> 7 6 5 <br/> Number of moves: 5 <br/> Number of States examined: 19 <br/> */