1 Задание 1.1 Постановка задачи Даны три стержня и n дисков различного размера. Диски можно надевать на стержни, образуя из них башни. Перенести n дисков со стержня А на стержень С, сохранив их первоначальный порядок. При переносе дисков необходимо соблюдать следующие правила: на каждом шаге со стержня на стержень переносить только один диск; диск нельзя помещать на диск меньшего размера; для промежуточного хранения можно использовать стержень В. Реализовать алгоритм, используя три стека вместо стержней А, В, С. Информация о дисках хранится в исходном файле. 1.2 Анализ задачи Ханойская башня Исходная башня: 15 9 7 5 Сортируем массив: 5 7 9 15 Башня: 5 7 9 15 Шаг 1 2 3 4 5 6 7 8 9 A 7 9 15 9 15 9 15 15 5 15 5 15 15 B 5 5 9 9 79 579 579 79 C 7 57 57 7 15 5 15 Шаг A B C 10 7 9 5 15 11 57 9 15 12 57 9 15 13 7 5 9 15 14 15 5 7 9 15 5 7 9 15 1.3 Алгоритмы решения задачи Рисунок 1 – Скриншот блок-схемы Рисунок 2 – Скриншот блок-схемы Рисунок 3 – Скриншот блок-схемы print_stack(Stack* stack) t != NULL t->x t = t->next конец get_size(Stack* stack) t != NULL size++; t = t->next return size swap(Stack** s1, Stack** s2) d1==-1 pop(s2); push(s1, d2); d2==-1 pop(s1); push(s2, d1); d1>d2 pop(s1); push(s2, d1) pop(s2); push(s1, d2); конец sort(int* arr) int i = 0; i < 9; i++ int j = 8; j >= i; j-- arr[j] < arr[j + 1] temp = arr[j]; arr[j] = arr[j + 1]; arr[j + 1] = temp; конец Рисунок 4 – Скриншот блок-схемы Рисунок 5 – Скриншот блок-схемы 1.4 Таблица переменных Смысл Обозначение Обозначение Тип переменных в алгоритме в программе перемен ной Исходные x,n,i x, n,i int Промежуточные q, d1,d2 q, d1,d2 int Результаты t int t 1.5 Программа на СИ #include <iostream> #include <fstream> using namespace std; struct Node { int x; Node* next; }; int get_top(Node* stack) { if (stack != NULL) return stack->x; else return -1; } void pop(Node** stack) { Примечания if (stack != NULL) { Node* rm = *stack; if (*stack != NULL) { *stack = (*stack)->next; } delete rm; } } void push(Node** stack, int x) { Node* n = new Node; n->x = x; n->next = *stack; *stack = n; } void print_stack(Node* stack, char c) { cout << c << ": "; Node* t = stack; while (t != NULL) { cout << t->x << " "; t = t->next; } cout << endl; } void swap(Node** s1, Node** s2) { int d1 = get_top(*s1); int d2 = get_top(*s2); if (d1 == -1) { pop(s2); push(s1, d2); } else if (d2 == -1) { pop(s1); push(s2, d1); } else if (d1 > d2) { pop(s2); push(s1, d2); } else { pop(s1); push(s2, d1); } } int get_size(Node* stack) { int size = 0; Node* t = stack; while (t != NULL) { size++; t = t->next; } return size; } void sort(int* arr) { int temp; for (int i = 0; i < 9; i++) { for (int j = 8; j >= i; j--) { if (arr[j] < arr[j + 1]) { temp = arr[j]; arr[j] = arr[j + 1]; arr[j + 1] = temp; } } } } int main() { setlocale(LC_ALL, "Russian"); Node* A = NULL; Node* B = NULL; Node* C = NULL; int n = 0; ifstream fin("input.txt"); int t; int arr[10]; for (int i = 0; i < 10; i++) { arr[i] = 0; } for (int i = 0; fin >> t; i++) { arr[i] = t; } sort(arr); for (int i = 0; i < 10; i++) { if (arr[i] != 0) { push(&A, arr[i]); n++; } } fin.close(); cout << "Исходная башня\n"; print_stack(A, 'A'); int i = 0; while (get_size(C) != n) { i++; //+1 шаг if (i % 3 == 1) swap(&A, &B); else if (i % 3 == 2) swap(&A, &C); else if (i % 3 == 0) swap(&C, &B); cout << "\nШаг №" << i << ":\n"; print_stack(A, 'A'); print_stack(B, 'B'); print_stack(C, 'C'); } } 1.6 Результаты Рисунок 6- Скриншот результата Рисунок 7 – Скриншот результата Рисунок 8 – Скриншот результата 2 Вывод Результаты программы совпадают с ручным подсчётом, программа работает верно