Помощь - Поиск - Пользователи - Календарь
Полная версия: рекурсивнвный подсчет как распределить мальчиков и девочек
Форум «Всё о Паскале» > Pascal, Object Pascal > Задачи
maksimla
В поездке ученики прибыли в n (0 < n ≤ 15) этажный дом. На одном этаже могут жить только одного пола дети.Учительница должда распределить их придерживаясь правилам с этажом нижей девочки могут жить над мальчиками и над девочками но мальчики могут жить только над девачками. На первом этаже могут жить и девачки и мальчики.
Напишите программу котоорая данным n написала сколько всго можит быть вариантов расселения учеников. Два разных варианта расселения считаются разными когда на одном сперва мальчики а потом девочки живут.
Первичные данные
3
результат
5
Обьяснение
когда n = 3 то тогда вариантов расселения есть 5 ддд,мдд,дмд,мдм,ддм.
Д это девачка М это мальчик.
Но ммд и дмм так неможит быть.
Я совсем нечего непридумал как надо сделать и как останавливать сам цикл может дадите идею как это так сделать
volvo
Ну, так и пиши, по заданию:
function count(const n: integer; s: string): integer;
begin
if length(s) = n then begin { условие выхода: число этажей достигнуто }
writeln(s); count := 1;
end
else begin
if (s = '') or (s[length(s)] = 'f') then
{ или первый этаж, или над девочками - могут быть кто угодно }
count := count(n, s + 'm') + count(n, s + 'f')
else
{ над мальчиками - только девочки }
count := count(n, s + 'f');
end;
end;
Как вызвать - разберешься?

Это работает. Для 5 этажей выдает 13 комбинаций, для 12-ти этажей - 377, ... Разберись, как оно работает, и допиши программу...

Добавлено через 1 мин.
P.S. В принципе, можно, подобрать формулу, вычисляющую ответ без перебора (в общем-то оно и без подбора ясно: это все числа Фибоначчи), но у тебя в задании именно рекурсия, придется вычислять.
maksimla
Вот кажется разобрался как вызвать

program varenti_raspredilenija;

function count(const n: integer; s: string): integer;
begin
if length(s) = n then begin
writeln(s); count := 1;
end
else begin
if (s = '') or (s[length(s)] = 'Д') then
count := count(n, s + 'М') + count(n, s + 'Д')
else
count := count(n, s + 'Д');
end;
end;
var x:integer;
begin
WriteLn('Vvedi cislo ot 0 do 15');
Readln(x);
writeln(count(x,''));
readln;
end.

кажется все правильно и вызывает и результат выводит
и разобрался вот с этим s[length(s)] = 'Д'
program Bevarde2;
var s:string;
begin
s:='МД';
WriteLn(s[length(s)] = 'Д');
Readln;
end.

но запутался в рекурсии как она так считает нечего непонял хоть выполнял с n=2 и пошагово
count := count(n, s + 'М') + count(n, s + 'Д') и тут ведь наверное ошибка должна быть это мне просто так кажется вот и незнаю как тут складывается и как выполняется все остальное

Добавлено через 6 мин.
И тут если взять что я вижу то только n=2 то тогда результат МД все
s + 'М' это так понимаю blush.gif

Добавлено через 2 мин.
а я даже и неподумал что это числа Фибоначчи
volvo
Цитата
и тут ведь наверное ошибка должна быть
Ну, если б должна была быть - тебе бы наверное компилятор сказал бы об этом? Раз не говорит - значит нету smile.gif

Опять же, ты, видимо до сих пор с рекурсией не разобрался... Ее не пошагово прогонять надо, а взять лист бумаги и написать все, что куда передается. Вот смотри (для простоту возьмем N = 2):
0) count(2, '');
s = '', условие выхода не достигнуто, продолжаем: s = '', значит результат будет равен count(2,'m')+count(2,'f')
1) count(2, 'm'):
s = 'm', опять же выходить рано, идем дальше: последний символ = 'm', значит результат будет = count(2,'mf')
a) count(2, 'mf');
s = 'mf', все, дошли до второго этажа, результат = 1, он передается НАЗАД, в предыдущую формулу, в пункте (1), то есть, count(2,'m') = count(2,'mf') = 1... Это в свою очередь возвращается в формулу (0):
count(2, '') = count(2,'m') + count(2,'f') = (заменяем рекурсивный вызов уже полученным результатом) = 1 + count(2,'f') (формула №4)

Что у нас осталось неизвестным? Count(2, 'f')? Вот так же, как я расписывал все предыдущие вызовы, распиши это, и посмотри, чему будет равно это выражение, а потом результат подставишь в формулу №4 и увидишь, чему будет равно общее значение функции...
maksimla
1 b) по условию count(2,'f') сравниваем s[length(s)] = 'f' да и тогда будит результат равен count(2,'fm')+count(2,'ff')
2)
a) count(2,'fm')
s = 'fm', все, дошли до второго этажа, результат = 1, он передается НАЗАД, в предыдущую формулу, в пункте (1 b),
count(2,'fm')+count(2,'ff') 1+count(2,'ff')
2 b) s = 'fm', все, дошли до второго этажа, результат = 1, он передается НАЗАД, в предыдущую формулу, в пункте (1 b), count(2,'fm')+count(2,'ff') count:=1+1;
3) count:=1+1; передается в пункт 0 и получается count:=1+2; и тогда count:=3;
volvo
Молодец. Теперь понятнее, как собирается конечный результат в рекурсивных функциях?
maksimla
даже незнаю можетбыть более менее понятно спасибо
Это текстовая версия — только основной контент. Для просмотра полной версии этой страницы, пожалуйста, нажмите сюда.