kutuzzzov

Спринт 4. Урок 7. Ханойская башня

Dec 26th, 2021 (edited)
359
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 2.99 KB | None | 0 0
  1. #include <iostream>
  2. #include <stdexcept>
  3. #include <vector>
  4.  
  5. using namespace std;
  6.  
  7. class Tower {
  8. public:
  9.     // конструктор и метод SetDisks нужны, чтобы правильно создать башни
  10.     Tower(int disks_num) {
  11.         FillTower(disks_num);
  12.     }
  13.  
  14.     int GetDisksNum() const {
  15.         return disks_.size();
  16.     }
  17.  
  18.     void SetDisks(int disks_num) {
  19.         FillTower(disks_num);
  20.     }
  21.  
  22.     // добавляем диск на верх собственной башни
  23.     // обратите внимание на исключение, которое выбрасывается этим методом
  24.     void AddToTop(int disk) {
  25.         int top_disk_num = disks_.size() - 1;
  26.         if (0 != disks_.size() && disk >= disks_[top_disk_num]) {
  27.             throw invalid_argument("Невозможно поместить большой диск на маленький");
  28.         } else {
  29.             // допишите этот метод и используйте его в вашем решении
  30.             disks_.push_back(disk);
  31.         }
  32.     }
  33.  
  34.     // вы можете дописывать необходимые для вашего решения методы
  35.     int RemoveFromTop() {
  36.         int disk = disks_.back();
  37.         disks_.pop_back();
  38.         return disk;
  39.     }
  40.  
  41. private:
  42.     vector<int> disks_;
  43.  
  44.     // используем приватный метод FillTower, чтобы избежать дубликации кода
  45.     void FillTower(int disks_num) {
  46.         for (int i = disks_num; i > 0; i--) {
  47.             disks_.push_back(i);
  48.         }
  49.     }
  50. };
  51.  
  52.  // disks_num - количество перемещаемых дисков
  53.  // destination - конечная башня для перемещения
  54.  // buffer - башня, которую нужно использовать в качестве буфера для дисков
  55. void MoveDisks(int amount, Tower& source, Tower& destination, Tower& buffer) {
  56.      if (amount > 1) {
  57.          MoveDisks(amount-1, source, buffer, destination);
  58.      }
  59.     int disk = source.RemoveFromTop();
  60.     destination.AddToTop(disk);
  61.     if (amount > 1) {
  62.          MoveDisks(amount-1, buffer, destination, source);
  63.      }
  64. }
  65.  
  66. void SolveHanoi(vector<Tower>& towers) {
  67.      int disks_num = towers[0].GetDisksNum();
  68.      // запускаем рекурсию
  69.      // просим переложить все диски на последнюю башню
  70.      // с использованием средней башни как буфера
  71.      MoveDisks(disks_num, towers[0], towers[2], towers[1]);
  72. }
  73.  
  74. int main() {
  75.     int towers_num = 3;
  76.     int disks_num = 3;
  77.     vector<Tower> towers;
  78.     // добавим в вектор три пустые башни
  79.     for (int i = 0; i < towers_num; ++i) {
  80.         towers.push_back(0);
  81.     }
  82.     // добавим на первую башню три кольца
  83.     towers[0].SetDisks(disks_num);
  84.  
  85.     SolveHanoi(towers);
  86. }
Add Comment
Please, Sign In to add comment