Рекурсивні означення та підпрограми, Детальна інформація

Рекурсивні означення та підпрограми
Тип документу: Реферат
Сторінок: 7
Предмет: Комп`ютерні науки
Автор: Олексій
Розмір: 17.1
Скачувань: 1082
На дошці є три голки: 1, 2, 3. На голці 1 розміщена вежа з n дисків; нижній диск має найбільший діаметр, а діаметр кожного наступного менший від попереднього. За один хід із будь-якої голки можна взяти верхній диск і перемістити на іншу, але дозволено класти диск лише на дошку або на диск більшого діаметра. Треба перемістити усю вежу з голки 1 на голку 3.

Ця гра називається "Ханойські вежі", оскільки за легендою з n=64 дисками її почали понад 1000 років тому ченці в одному монастирі поблизу Ханоя у В'єтнамі; коли вони закінчать її, настане кінець світу. Розв'язанням цієї гри-задачі є послідовність перенесень дисків. Написати програму друкування позначень цих перенесень.

Для перенесення вежі висотою n дисків з голки 1 на голку 3 необхідно перенести вежу висотою n-1 на голку 2, потім перенести нижній диск на голку 3 та перенести вежу з голки 2 на голку 3. При перенесенні вежі з 1 на 2 допоміжною є голка 3, а при перенесенні з 2 на 3 – голка 1. Інша послідовність дій неможлива. Отже, розв'язання задачі для вежі висотою n описується через розв'язання задачі для вежі висотою n-1.

Позначимо disk(a,b) перенесення одного диску з голки a на голку b, tow(h, a, b, c) – перенесення вежі висотою h з голки a на b з використанням голки c як допоміжної (tow – це скорочення від tower, або вежа). За h>1 виконання tow(h, a, b, c) зводиться до виконання

tow(h-1, a, c, b); disk(a, b); tow(h-1, c, b, a),

а за h=1 – до виконання

disk(a, b).

Отже, маємо програму:

program Hantow(input, output);

var n : integer;

procedure disk(f, t : integer);

begin writeln(f, '->', t) end;

procedure tow(h : integer; f, t, v : integer);

begin

if h=1 then disk(f, t) else

begin

tow(h-1, f, v, t); disk(f, t); tow(h-1, v, t, f)

end

end;

begin readln(n); tow(n, 1, 3, 2) end.

Очевидно, що глибина рекурсії викликів цієї процедури дорівнює значенню їх першого аргументу h.

Визначимо кількість переносів дисків як функцію f(n), де n – висота вежі. Очевидно, що f(1)=1, і що f(n)=2\xF0D7 f(n-1)+1. За принципом індукції неважко довести, що f(n)=2n-1. Значення f(64) дорівнює приблизно 1022. Якщо припустити, що кожної секунди ченці переносять один диск, то для переносу такої вежі потрібно приблизно 1015 років! Навіть якщо припустити, що комп'ютер здатний щосекунди друкувати по сто тисяч позначень переносів, то й тут знадобиться 1010 років. Кінець світу, мабуть, настане раніше…

4. "Індійський алгоритм" піднесення до степеня

Цей алгоритм обчислення натурального n-го (n>0) степеня цілого числа x виглядає зовсім просто:

за n=1 xn = x,

за n>1 xn = xn mod 2\xF0D7 (xn div 2)2.

Основна мета цього алгоритму – скоротити кількість множень при піднесенні до степеня. Наприклад, за цим алгоритмом x5=x\xF0D7 (x2)2, тобто достатньо три множення замість чотирьох: x\xF0D7 x\xF0D7 x\xF0D7 x\xF0D7 x. Одне множення економиться за рахунок того, що x2 зберігається як проміжне значення і множитися само на себе. Так само x10=1\xF0D7 (x5)2=(x5)2, що вимагає лише чотирьох множень (три з них для обчислення x5) замість дев'яти "лобових". Але тут доведеться зберігати спочатку x2, а потім x5.

Як бачимо, обчислення xn зводиться до обчислення xndiv2, запам'ятання його, піднесення до квадрату, та множення його на x за непарного n. Отже, обчислення xn описується рекурсивною функцією

function pow(x, n : integer) : integer;

var t : integer;

The online video editor trusted by teams to make professional video in minutes