Question address: http://acm.hdu.edu.cn/showproblem.php? PID = 1, 1240
The question description is very long. In fact, the question is very simple-in a three-dimensionalCubeIn the body, find the shortest distance between two coordinate points. The data size is not large, and the side length is mostly 10, that is, a total of 1000 coordinate points. Maybe BFS can also be used as a, but I still prefer faster *. So the focus of this question is to write *AlgorithmFirst, paste a pseudo A * AlgorithmCode(I have reposted it before, but I haven't posted it all ):
Add start to open list </P> <p> while open not empty </P> <p> Get node N from open that has the lowest f (N) </P> <p> if n is goal then return path </P> <p> move n to closed </P> <p> for each n' = canmove (n, direction) </P> <p> G (n') = g (n) + 1 </P> <p> calculate H (n ') </P> <p> If n' in Open list and new N' is not better, continue </P> <p> If n' in closed list and new N' is not better, continue </P> <p> remove any n' from open and closed </P> <p> Add N as n's parent </P> <p> Add N' to open </P> <p> end for </P> <p> end while </P> <p> if we get to here, then there is no solution
Address: http://blog.minstrel.idv.tw/2004/12/star-algorithm.html
With a detailed introduction to the * algorithm, you may need to flip the wall.
My code is written based on the above pseudo code, so we need to use the data structure of the Open table and the closed table. They need to support fast addition, deletion, and query operations, so I thought of the STL map template class-coordinate as the query keyword, and saved the nodes F (N), g (N), H (n) as the value. The following code adds a comment:
# Include <iostream> <br/> # include <map> <br/> # include <cmath> <br/> # include <string> <br/> # include <cstdio> </P> <p> using namespace STD; </P> <p> const int INF = 1000000; // indicates the reachable distance between two points, infinity <br/> const int dirs [6] [3] = {1, 0, 0, 0, 1, 0, 0, 0, 1,-1, 0, 0, 0,-1, 0, 0, 0,-1 }; // six directions in the 3D space </P> <p> struct location <br/>{< br/> int X _, Y _, Z _; </P> <p> int getidealdis (const Location & LOC) const // H function in a * algorithm, estimated two The shortest distance between Points <br/>{< br/> return FABS (X _-loc. X _) + FABS (Y _-loc. Y _) + <br/> FABS (Z _-loc. Z _); <br/>}</P> <p> location getnext (const Int & Index) const // calculate adjacent points in six directions, 0 <= index <= 5 <br/> {<br/> location LOC; <br/> loc. X _ = X _ + dirs [Index] [0]; <br/> loc. Y _ = Y _ + dirs [Index] [1]; <br/> loc. Z _ = Z _ + dirs [Index] [2]; <br/> return LOC; <br/>}</P> <p> bool isequal (const Location & LOC) const <br/>{< br/> retu Rn X _ = loc. X _ & Y _ = loc. Y _ & <br/> Z _ = loc. Z _; <br/>}< br/> }; </P> <p> struct node // used to save the values of the three functions of a * algorithm node <br/>{< br/> int F _, G _, H _; <br/> }; </P> <p> struct CMP // template parameter used for Map <br/> {<br/> int getindex (const Location & LOC) const <br/> {<br/> return 100 * loc. X _ + 10 * loc. Y _ + loc. Z _; <br/>}</P> <p> bool operator () (const Location & A, const Location & B) const <br/>{< br/> return getindex (a)-getindex (B)> 0; <br/>}< br/> }; </P> <p> struct space // cube class <br/> {<br/> char eles _ [1000]; // The value corresponding to the coordinate point, X indicates inaccessible, and O indicates accessible <br/> int length _; // cube edge length <br/> typedef Map <location, node, CMP> nodemap; <br/> typedef pair <location, node> mappair; // typedef is written in the class to prevent name contamination (of course, writing the problem-solving code is meaningless ); nodemap is the type of Open table and close table </P> <p> int getindex (const Location & LOC) const <br/> {<br/> return length _ * loc. Z _ + Length _ * loc. Y _ + Loc. X _; <br/>}</P> <p> char getele (const Location & LOC) const <br/>{< br/> return eles _ [getindex (LOC)]; <br/>}</P> <p> void setele (const Location & Loc, const char & C) <br/>{< br/> eles _ [getindex (LOC)] = C; <br/>}</P> <p> bool islocationlegal (const Location & LOC) const // determine whether the coordinates are out of bounds <br/>{< br/> return loc. X _> = 0 & loc. X _ <length _ & <br/> loc. Y _> = 0 & loc. Y _ <length _ & <br/> loc. Z _> = 0 & loc. Z _ <Length _; <br/>}</P> <p> mappair getpair (const nodemap & node_map) const // find the node with the smallest F value in the Open table used in the * algorithm <br/>{< br/> nodemap & map = const_cast <nodemap &> (node_map ); <br/> mappair min_pair = * map. begin (); <br/> int min_f = min_pair.second.f _; <br/> nodemap: iterator it; <br/> for (IT = map. begin (); it! = Node_map.end (); ++ it) {<br/> const Int & F = it-> second. F _; <br/> If (F <min_f) {<br/> min_f = f; <br/> min_pair = * it; <br/>}</P> <p> return min_pair; <br/>}</P> <p> int getmindis (const Location & start_loc, const Location & goal_loc) const // A * algorithm. astaralgorithm is a confusion caused by not exposing the internal implementation method of the interface. Of course, it doesn't matter here ...... <Br/>{< br/> nodemap open_table, closed_table; <br/> node. g _ = 0; // G indicates the distance from the current coordinate point to the start point <br/> node. H _ = start_loc.getidealdis (goal_loc); // H indicates the shortest possible distance from the current coordinate point to the end point <br/> node. F _ = node. g _ + node. H _; // F = G + H. The nodes with the minimum F value are extended from the Open Table each time below, it can be ensured that the final distance obtained is the shortest <br/> open_table [start_loc] = node; // After defining the Start Node, put it into the Open Table </P> <p> while (! Open_table.empty () {<br/> mappair pair = getpair (open_table); // The node with the smallest F value from the Open Table <br/> If (pair. first. isequal (goal_loc) return pair. second. g _; <br/> open_table.erase (pair. first); <br/> closed_table [pair. first] = pair. second; // move the node to the closed table </P> <p> for (INT I = 0; I <6; ++ I) {// I indicates six directions <br/> location next_loc = pair. first. getnext (I); // obtain the adjacent coordinates in the I direction <br/> If (! Islocationlegal (next_loc) continue; // determine whether the coordinates are out of bounds <br/> If (getele (next_loc) = 'X') continue; // whether the coordinate point is accessible </P> <p> node next_node; <br/> next_node.g _ = pair. second. g _ + 1; // run here, indicating that this adjacent coordinate point can be moved <br/> next_node.h _ = next_loc.getidealdis (goal_loc ); <br/> next_node.f _ = next_node.g _ + next_node.h _; // define the node and find G, H, F </P> <p> nodemap :: iterator p_open_pair = open_table.find (next_loc); <br/> If (p_open_pair! = Open_table.end () & <br/> p_open_pair-> second. F _ <= next_node.f _) continue; // if the same coordinate point already exists, the node is better to be extended. Continue <br/> nodemap: iterator p_closed_pair = closed_table.find (next_loc ); <br/> If (p_closed_pair! = Closed_table.end () & <br/> p_closed_pair-> second. F _ <= next_node.f _) continue; // if the same coordinate point already exists, the better node has been extended. Continue </P> <p> If (p_open_pair! = Open_table.end () open_table.erase (p_open_pair); <br/> If (p_closed_pair! = Closed_table.end () closed_table.erase (p_closed_pair); // clear a node that is not the best <br/> open_table [next_loc] = next_node; // Insert a new node to the Open Table <br/>}</P> <p> return INF; // when it is run, it indicates that the two nodes are not reachable, return infinity <br/>}< br/>}space; </P> <p> int main () <br/>{< br/> string start_str; </P> <p> while (Getline (CIN, start_str) {<br/> space. length _ = start_str [6]-'0'; <br/> const Int & length = space. length _; </P> <p> for (Int J = 0; j <length * length; ++ J) {<br/> CIN> space. eles _ [J]; <br/> If (J % length = length-1) getchar (); <br/>}</P> <p> location start_loc, goal_loc; <br/> CIN> start_loc.x _> start_loc.y _> start_loc.z _> <br/> goal_loc.x _> goal_loc.y _> goal_loc.z _; <br/> getchar (); </P> <p> int Len = space. getmindis (start_loc, goal_loc); <br/> If (LEN <inf) {<br/> cout <space. length _ <''<Len <Endl; <br/>} else {<br/> cout <" No route "<Endl; <br/>}</P> <p> string end_str; <br/> Getline (CIN, end_str ); <br/>}</P> <p> return 0; <br/>}
What's wrong? I hope the scalpers will not correct me ~