Предел выполнения рекурсии
Добрый всем день или доброе утро а может и ночь! Мне нужно решить такую задачу (рекурсия обязательна)
есть схема состоящая из кусков по 3 резистора. Ее длина задаться в задаче как число которое вводит пользователь. Каждый резистор имеет сопротивление 1 Ом (пускай будет R для центрального резистора в каждом куске) значит ли это что сопротивление 1 куска равно 1+1+1=3 но это для последовательного соединения дальше идёт параллельное а значит сопротивление будет равно ((1+1+1)*1)/((1+1+1)+1) а для самой задачи это будет формулой R=(R+2)/(R+3) у меня задача реализована на питоне и с++ но проблема остаться такой же, при вводе большого числа типа 32000 в с++ и 3000 в питоне код выдает ничего, просто пустой экран с ретурн и большое число. Также если можно то поправьте мой код на обеих языках. Спасибо!
Питон
import sys
sys.setrecursionlimit(5000)
def Rx(r):
global ans
if(r>1):
Rx(r-1)
ans=(ans+2)/(ans+3)
return ans
a=int(input())
ans=1.0
if(a!=1):
print (Rx(a)+2)
else:
print(3)
С++
#include <iostream>
#include <iomanip>
using namespace std;
float ans=1;
float Rx(long long r)
{
if(r>1){
Rx(r-1);
}
return ans=(ans+2)/(ans+3);
}
int main()
{
long long a;
cin >> a;
if(a!=1){
cout << fixed << setprecision(15)<<Rx(a)+2;
}
else{
cout << 3;
}
}
Ответы (1 шт):
Обе версии написаны неправильно. Например, вызов Rx никуда не записывается, так какой смысл возвращать (глобальный) ans?
Вот так фурычит:
def recres(numc):
if numc <= 1:
return 3
res = recres(numc - 1)
return 2 + res/(1+res)
Формула тут такая - имея сопротивление res, мы добавляем параллельное ему 1, получается res * 1 / (res + 1), и добавляем 2 для двух последовательных резисторов.
Или так (переформируем дробь, чтобы одно использование было)
def recres(numc):
if numc <= 1:
return 3
return 3 - 1 / (1 + recres(numc - 1))
Рекурсия по сути не нужна, достаточно цикла
def resist(numc):
if numc <= 0:
return None
res = 3
for i in range(numc - 1):
res = 2 + res/(1+res)
return res
Однако для длинных цепочек считать особо и не нужно, т.к. сходимость ряда очень быстрая, точности дабла не хватит, чтобы заметить различия после длины цепи 15. Получается, 32000 шагов - впустую.
Но есть у нас методы против Кости Сапрыкина, в советской школе давали.
При соединении бесконечно длинной цепочки с ещё одним звеном сопротивление не меняется, значит, можем записать
r*1/(r+1) + 2 = r
r^2 - 2r - 2 = 0
Решив квадратное уравнение, получим точный ответ
r = 1 + sqrt(3)

