Advertisement
wurdalak007

Untitled

Mar 18th, 2018
165
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 4.91 KB | None | 0 0
  1. #include <iostream>
  2. #include <set>
  3. #include <map>
  4. #include <string>
  5. #include <vector>
  6. using namespace std;
  7.  
  8. typedef vector<int> Vertex;
  9.  
  10. class Graph {
  11. public:
  12. Graph( vector<int>& StartCondition );
  13. bool HasASolution();
  14. void GetNextVert(Vertex& v, vector<Vertex>& next);
  15. void AStar();
  16. void PrintAns();
  17. char WhichMove( Vertex from, Vertex to );
  18. int CountTheHeuristic( Vertex v );
  19. private:
  20. Vertex Start;
  21. Vertex Final;
  22. map<Vertex, int> f;
  23. map<Vertex, int> g;
  24. map<Vertex, Vertex> parents;
  25. };
  26.  
  27. char Graph::WhichMove( Vertex from, Vertex to ) {
  28. int FirstSpacePosition = 0;
  29. int SecSpacePosition = 0;
  30. for( int i = 0; i < 16; i++ ) {
  31. if( from[i] == 0 ){
  32. FirstSpacePosition = i;
  33. break;
  34. }
  35. }
  36. for( int i = 0; i < 16; i++ ) {
  37. if( to[i] == 0 ){
  38. SecSpacePosition = i;
  39. break;
  40. }
  41. }
  42.  
  43. switch (SecSpacePosition - FirstSpacePosition) {
  44. case 1:
  45. return 'R';
  46. break;
  47. case -1:
  48. return 'L';
  49. break;
  50. case 4:
  51. return 'D';
  52. break;
  53. case -4:
  54. return 'U';
  55. default:
  56. break;
  57. }
  58. return 0;
  59. }
  60.  
  61. void Graph::PrintAns() {
  62. int NumOfMoves = 0;
  63. string ReverseWay;
  64. Vertex tmp = Final;
  65. while( tmp != Start ) {
  66. NumOfMoves++;
  67. Vertex prev = parents[tmp];
  68. ReverseWay += WhichMove(tmp, prev);
  69. tmp = prev;
  70. }
  71.  
  72. cout << NumOfMoves << endl;
  73. for( int i = (int)ReverseWay.length()-1; i >=0; i-- ) {
  74. cout << ReverseWay[i];
  75. }
  76.  
  77. }
  78.  
  79. void Graph::AStar() {
  80. if( !HasASolution() ) {
  81. cout << -1;
  82. exit(0);
  83. }
  84. set<pair<int,Vertex>> q;
  85. set<Vertex> used;
  86.  
  87. g.insert(pair<Vertex, int>(Start, 0));
  88. f.insert(pair<Vertex, int>(Start, g[Start] + CountTheHeuristic(Start)));
  89. q.insert(pair<int,Vertex>(f[Start], Start));
  90.  
  91. while(!q.empty()) {
  92. Vertex tmp = q.begin()->second;
  93. q.erase(q.begin());
  94.  
  95. if( tmp == Final ) {
  96. PrintAns();
  97. exit(0);
  98. }
  99.  
  100. used.insert(tmp);
  101. vector<Vertex> NextVert;
  102. GetNextVert(tmp, NextVert);
  103.  
  104. for( auto v : NextVert ) {
  105. int TentScore = g[tmp] + 1;
  106. if( used.find(v) != used.end() && TentScore >= g[v] ) {
  107. continue;
  108. }
  109. if( used.find(v) == used.end() || TentScore < g[v] ) {
  110. parents.insert(pair<Vertex, Vertex>(v,tmp));
  111. g.insert(pair<Vertex, int>(v,TentScore));
  112. f.insert(pair<Vertex, int>(v,g[v] + CountTheHeuristic(v)));
  113. if( q.find({f[v],v}) == q.end() )
  114. q.insert(pair<int, Vertex>(f[v],v));
  115. }
  116. }
  117.  
  118. }
  119. }
  120.  
  121. int Graph::CountTheHeuristic( Vertex v ) {
  122. int Heuristic = 0;
  123. for( int i = 0; i < v.size(); i++ ) {
  124. int elem = v[i];
  125. if( elem == 0 ) {
  126. Heuristic += (3 - i/4) + (3 - i%4);
  127. }
  128. if( i == 15 && elem == 0) {
  129. Heuristic += 0;
  130. } else {
  131. Heuristic += (abs(elem-1-i)/4)+(abs(elem-1-i)%4);
  132. }
  133. }
  134. return Heuristic;
  135. }
  136.  
  137. void Graph::GetNextVert( Vertex& v, vector<Vertex>& next ) {
  138. int SpacePosition = 0;
  139. for( int i = 0; i < 16; i++ ) {
  140. if( v[i] == 0 ){
  141. SpacePosition = i;
  142. break;
  143. }
  144. }
  145. int i = 0;
  146. if( SpacePosition < 15 ) {
  147. next.push_back(v);
  148. swap(next[i][SpacePosition], next[i][SpacePosition+1]);
  149. i++;
  150. }
  151.  
  152. if( SpacePosition > 0 ){
  153. next.push_back(v);
  154. swap(next[i][SpacePosition], next[i][SpacePosition-1]);
  155. i++;
  156. }
  157.  
  158. if( SpacePosition >= 4 ){
  159. next.push_back(v);
  160. swap(next[i][SpacePosition], next[i][SpacePosition-4]);
  161. i++;
  162. }
  163.  
  164. if( SpacePosition <= 11 ){
  165. next.push_back(v);
  166. swap(next[i][SpacePosition], next[i][SpacePosition+4]);
  167. }
  168.  
  169. }
  170.  
  171. Graph::Graph( vector<int>& g )
  172. {
  173. int j = 1;
  174. for(auto i : g){
  175. Start.push_back(i);
  176. Final.push_back(j);
  177. j++;
  178. }
  179. Final[15] = 0;
  180. }
  181.  
  182. bool Graph::HasASolution() {
  183. int inv = 0;
  184. for( int i = 0; i < 16; ++i )
  185. if (Start[i])
  186. for( int j = 0; j < i; ++j )
  187. if( Start[j] > Start[i])
  188. ++inv;
  189. for( int i = 0; i < 16; ++i )
  190. if( Start[i] == 0 )
  191. inv += 1 + i / 4;
  192. if ( (inv & 1) == 1) {
  193. return false;
  194. } else {
  195. return true;
  196. }
  197. }
  198.  
  199.  
  200. int main() {
  201. vector<int> g;
  202. for( int i = 0; i < 16; i++ ) {
  203. int tmp = 0;
  204. cin >> tmp;
  205. g.push_back(tmp);
  206. }
  207. Graph graph(g);
  208. graph.AStar();
  209. return 0;
  210. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement