Advertisement
Guest User

Untitled

a guest
Oct 30th, 2014
134
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 6.42 KB | None | 0 0
  1. #include <iostream>
  2. #include <map>
  3. #include <string>
  4.  
  5. using namespace std;
  6.  
  7. short abs(short A) //модуль числа(не знаю зачем написал)
  8. {
  9.     return A > 0 ? A : -A;
  10. }
  11.  
  12. class matrix //класс хранящий информацию о текущем состоянии восемнашек + перегруженные операторы
  13. {
  14. private:
  15.    
  16.     int ST;
  17.     short matr[12]; // в 0..8 хранится сама матрица, в 9 хранится значение манхэттеновского расстояния для доски, в 10 и 11 хранятся номера клеток которые мы поменяли последний раз
  18.    
  19. public:
  20.    
  21.     matrix(){}
  22.     matrix(short temp[9])
  23.     {
  24.         for (short i = 0; i < 9; ++i)
  25.             matr[i] = temp[i];
  26.     }
  27.    
  28.     void shift(short i, short n) //поменять местами что-то и 0
  29.     {
  30.         matr[10] = i;
  31.         matr[11] = n;
  32.         n *= 2;
  33.         ++n;
  34.         matr[9] -= abs(i / 3 - ((matr[i] + 8) % 9) / 3)
  35.         + abs(i % 3 - ((matr[i] + 8) % 9) % 3)
  36.         + abs((i + n) / 3 - ((matr[i + n] + 8) % 9) / 3)
  37.         + abs((i + n) % 3 - ((matr[i + n] + 8) % 9) % 3);
  38.        
  39.         short k = matr[i];
  40.         matr[i] = matr[i + n];
  41.         matr[i + n] = k;
  42.        
  43.         matr[9] += abs(i / 3 - ((matr[i] + 8) % 9) / 3)
  44.         + abs(i % 3 - ((matr[i] + 8) % 9) % 3)
  45.         + abs((i + n) / 3 - ((matr[i + n] + 8) % 9) / 3)
  46.         + abs((i + n) % 3 - ((matr[i + n] + 8) % 9) % 3);
  47.         ST += 1;
  48.     }
  49.    
  50.     matrix getParent() //возвращает предыдущее состояние восемнашек
  51.     {
  52.         if ((this->matr[10] == -1) || (this->matr[11] == -1))
  53.         {
  54.             return *this;
  55.         }
  56.         matrix temp(*this);
  57.         temp.shift(this->matr[10], this->matr[11]);
  58.         return temp;
  59.     }
  60.    
  61.     friend std::istream& operator >> (std::istream& in, matrix& m)
  62.     {
  63.         m.matr[9] = 0;
  64.         for (short i = 0; i < 9; ++i)
  65.         {
  66.            
  67.             in >> m.matr[i];
  68.             m.matr[9] += abs(i / 3 - ((m.matr[i] + 8) % 9) / 3);
  69.             m.matr[9] += abs(i % 3 - ((m.matr[i] + 8) % 9) % 3);
  70.         }
  71.         m.matr[10] = -1;
  72.         m.matr[11] = -1;
  73.         m.ST = 0;
  74.         return in;
  75.     }
  76.    
  77.     friend std::ostream& operator << (std::ostream& out, const matrix& m)
  78.     {
  79.         for (short i = 0; i < 9; ++i)
  80.         {
  81.             out << m.matr[i] << (i % 3 == 2 ? "\n" : " ");
  82.         }
  83.         out << "\n";
  84.         return out;
  85.     }
  86.    
  87.     friend bool operator== (const matrix& left, const matrix& right)
  88.     {
  89.         for (short i = 0; i < 9; ++i)
  90.         {
  91.             if (left.matr[i] != right.matr[i])
  92.             {
  93.                 return false;
  94.             }
  95.         }
  96.         return true;
  97.     }
  98.    
  99.     friend bool operator!= (const matrix& left, const matrix& right){return !(left == right);}
  100.    
  101.     short h(){return matr[9];}
  102.    
  103.     int steps(){return ST;}
  104.    
  105.     short find_zero()
  106.     {
  107.         for (short i = 0; i < 9; ++i)
  108.             if (matr[i] == 0)
  109.                 return i;
  110.         return 0;
  111.     }
  112.    
  113. };
  114.  
  115. matrix make_matrix(short temp[9]){return matrix(temp);}
  116.  
  117. class Vosm
  118. {
  119. private:
  120.    
  121.     matrix start;
  122.     matrix finish;
  123.     std::multimap < int, pair<matrix, string > > table; // h(x) + steps; matrix
  124.    
  125. public:
  126.    
  127.     Vosm()
  128.     {
  129.         std::cin >> start;
  130.     }
  131.    
  132.     void findSolve()
  133.     {
  134.         short temp[9] = {1, 2, 3, 4, 5, 6, 8, 7, 0};
  135.         finish = make_matrix(temp);
  136.         short q = start.h();
  137.         if (q == 0) //если расстояние 0 то ничего делать не надо
  138.         {
  139.             std::cout << "Yes\n0\n";
  140.             return;
  141.         }
  142.         string tmpstr;
  143.         table.insert(make_pair(0, make_pair(start, tmpstr)));
  144.         AStar();
  145.     }
  146.    
  147. private:
  148.    
  149.     /**
  150.      *   0 - right, 1 - down
  151.      */
  152.    
  153.     bool addV(matrix M, short i, short n, string path, char c)
  154.     {
  155.         matrix temp(M);
  156.         temp.shift(i, n); //меняем местами восемнашки i и n
  157.        
  158.         if (temp.h() == 2)
  159.         {
  160.             if (temp == finish)
  161.                 return false;
  162.         }
  163.         path.push_back(c);
  164.         if (temp != M.getParent()) //проверяем не возвращаемся ли мы в предыдущее состояние
  165.         {
  166.             table.insert(make_pair(temp.h() + temp.steps(), make_pair(temp, path)));
  167.         }
  168.         return true;
  169.     }
  170.    
  171.     void AStar() //в ходе алгоритма пробуем поменять восемнашку 0 с 4мя соседями(если это возможно)
  172.                  //и после этого добавляем состояние в multimap, где ключ это манхэттоновское расстояние
  173.     {
  174.         while(true)
  175.         {
  176.             matrix M = table.begin()->second.first;
  177.             string path = table.begin()->second.second;
  178.             table.erase(table.begin());
  179.            
  180.             short Z = M.find_zero();
  181.             if (Z % 3 < 2) //right
  182.             {
  183.                 if (addV(M, Z, 0, path, 'r') == false)
  184.                 {
  185.                     std::cout << "No\n";
  186.                     return;
  187.                 }
  188.             }
  189.             if (Z % 3 > 0) //left
  190.             {
  191.                 if (addV(M, Z - 1, 0, path, 'l') == false)
  192.                 {
  193.                     std::cout << "No\n";
  194.                     return;
  195.                 }
  196.             }
  197.             if (Z / 3 < 2) //down
  198.             {
  199.                 if (addV(M, Z, 1, path, 'd') == false)
  200.                 {
  201.                     std::cout << "No\n";
  202.                     return;
  203.                 }
  204.             }
  205.             if (Z / 3 > 0) //up
  206.             {
  207.                 if (addV(M, Z - 3, 1, path, 'u') == false)
  208.                 {
  209.                     std::cout << "No\n";
  210.                     return;
  211.                 }
  212.             }
  213.             int q = table.begin()->second.first.h();
  214.            
  215.             if (q == 0)
  216.             {
  217.                 std::cout << "Yes\n" << M.steps() + 1 << "\n" << table.begin()->second.second << "\n";
  218.                 return;
  219.             }
  220.         }
  221.     }
  222. };
  223.  
  224. int main()
  225. {
  226.     Vosm sheet;
  227.    
  228.     sheet.findSolve();
  229.    
  230.     return 0;
  231. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement