Консультация № 168971
05.06.2009, 08:05
0.00 руб.
0 11 4
Здравствуйте!
Только начинаю работать в Паскале, и помаленьку разбираю различные задачки и программы. В сборнике "Златопольский - Сборник задач по программированию" увидела такое задание: Вычислить сумму 1+ 1/3+ 1/(3*3)+1/(3*3*3)... Проблема в том, что есть условие- не использовать операцию возведение в степень. Помогите пожалуйста, как составить эту программу? Заранее благодарна.

Обсуждение

Неизвестный
05.06.2009, 08:39
общий
А в таких случаях никогда не следует использовать операцию возведения в степень типа pow(что, в какую): просто заведите переменную - слагаемое и каждый раз делите его (её) на 3
Неизвестный
05.06.2009, 10:14
общий
Boriss:
Если каждый раз делить на 3, то получится 1/3 + 1/(3+3) + 1/(3+3+3) ... т.е. замена умножениея сложением, а нам надо возведение в степень заменить умножением.

В одном цикле, который задает количество проходов, поместить вложенный цикл, который будет делать приращение знаменателя (3) ... (3*3) ... (3*3*3).

у меня получилось 0.49999153245609578486 при повторе цикла 10 раз (последнее выражение 1/(3^10) ).
Код:
Процедура Сформировать()
Х=10;
Результат=0;
ПриростТроек=1;
Для А=1 По Х Цикл
Для Б=1 По А Цикл
ПриростТроек=3*ПриростТроек;
КонецЦикла; //Б=1 По Х
ТекущееВыражение=1/ПриростТроек;
ПриростТроек=1;
Результат=Результат+ТекущееВыражение;
КонецЦикла; //А=1 По Х
Сообщить(Результат);
КонецПроцедуры
Неизвестный
05.06.2009, 10:50
общий
это ответ
Здравствуйте, Reresana.
Реализуется примерно так.
Код и описаните в приложении.
Вопросы - пишите.

Приложение:
const
n = 5; {количество элементов ряда}

var
i, j: integer;
summ, temp: real;

begin
summ:= 1; {начальное значение суммы (значение первого элемента ряда)}
for i:= 2 to n do
begin
temp:= 1;
for j:= 2 to i do temp:= temp / 3; {цикл вычисления текущего значения}
summ:= summ + temp; {суммирование}
end;
writeln(summ:6:4); {вывод суммы}
readln;
end.
5
Спасибо за помощь!
Неизвестный
05.06.2009, 10:57
общий
это ответ
Здравствуйте, Reresana.

Если внимательно посмотреть на члены данного ряда, можно заметить, что каждый следующий член можно представить как предыдущий, деленный на 3. Соответственно эту задачу можно решить таким образом:
Код:
...
sum:=1; {Сумма ряда}
pred:=1; {Предыдущий член ряда}
i:=1; {Счетчик}
while i<10 do begin {Условие окончания - 10 членов ряда просумировано}
sum:=sum+pred/3; {Увеличиваем сумму}
pred:=pred/3; {Текущий член, становится предыдущим}
inc(i); {Увеличиваем количество просуммированных членов на 1}
end;
...

Данный код подсчитает сумму 10-ти членов ряда.
К сожалению Вы не указали в вопросе условие окончания подсчета - обычно в задачах такого рода условием окончания служит заданная точность. Код для подсчета суммы с заданной точностью приведен ниже:
Код:
...
sum:=1; {Сумма ряда}
pred:=1; {Предыдущий член ряда}
e:=0.001; {Точность}
while pred>e do begin {Условие окончания - последний просуммированный член меньше, либо равен заданной точности}
sum:=sum+pred/3; {Увеличиваем сумму}
pred:=pred/3; {Текущий член, становится предыдущим}
end;
...

Ну вот вроде и все. Надеюсь понятно пояснил. Вопросы в мини-форум.
5
Спасибо за помощь! Этот код меня заинтересовал. Код на 10 членов ряда- Совершенно верно, Вы действительно правы, окончание подсчета должно быть 3 в 8 степени (этого я не указала), то есть 8 членов ряда. Код набрала, составила подсчет.
давно
Старший Модератор
31795
6196
05.06.2009, 11:03
общий
это ответ
Здравствуйте, Reresana.

1/(3*3)=(1/3)/3 и т.д.
Такие задачи можно решить двумя вариантами.
1) суммировать пока очередной элемент ряда превышает установленную точность;
2) суммировать первые N элементов ряда.
Удачи!

Приложение:
const
c=0.000001;{точность}
var
a,b:real;
d:integer;
begin
{первый вариант}
a:=0;
b:=1;
repeat
a:=a+b;{суммируем}
b:=b/3;{делим}
until b<c;{повторяем пока не достигнем нужной точности}
{ввыводим результат}
writeln('result:=',a:10:8);
{второй вариант}
a:=0;
b:=1;
d:=0;
repeat
a:=a+b;{суммируем}
b:=b/3;{делим}
inc(d);{увеличиваем счетчик}
until d=13;{повторяем пока не достигнем нужного элемента ряда}
{выводим результат}
writeln('result:=',a:10:8);
readln;
end.
5
Как правильно заметил Тимошенко Дмитрий, я не указала окончание ряда, и поэтому такой результат. Код набрала, спасибо большое за помощь! Для себя узнала, что такое "repeat until", и с чем его едят:)))
Об авторе:
Мне безразлично, что Вы думаете о обо мне, но я рад за Вас - Вы начали думать.

Неизвестный
05.06.2009, 11:07
общий
Если каждый раз делить на 3, то получится 1/3 + 1/(3+3) + 1/(3+3+3)
?????????????????????? и т.д.
1) 1
2) 1/3
3) (1/3)/3 = 1/(3*3) и еще раз и.тд.
И еще, это ведь сумма геометрической прогрессии (Геометрическая прогрессия)
Так что вот вам доказательство:
Окно программы:
Код:
Введите значение N: 10
1.49997459736829E+0000
1.49997459736829E+0000

Сама программа:
Код:
const mult: Double = 3;
VAR
sum, elem, exact: Extended;
i, N : Integer;
BEGIN
Write('Введите значение N: '); ReadLn(N);

elem := 1;
for i:=1 to N do elem := elem/mult;
exact := 1*(elem - 1)/(1/mult - 1);

sum := 0; elem := 1;
while N > 0 do
begin
sum := sum + elem;
elem := elem/mult; {и здесь используем только деление}
dec(N)
end;

WriteLn(sum);
WriteLn(exact);
END.

Неизвестный
05.06.2009, 11:44
общий
это ответ
Здравствуйте, Reresana.
Позволю себе добавить еще один способ решения этой задачи. Сразу оговорюсь, что вашего преподавателя по Pascal (если таковой имеется) он вряд ли устроит, но от этого он не станет менее правильным
Предложенная сумма есть не что иное, как геометрическая последовательность (о чем уже говорил Boriss в мини-форуме). При этом ее знаменатель q=1/3<1.
Для таких последовательностей существует вполне определенная математическая формула, которую (поскольку в задаче не указано количество суммируемых членов) можно применить: S=b1/(1-q).
Код - естественно - в приложении. Но в данном случае он не представляет ничего интересного

Приложение:
const q=1/3;
b1=1;
var s:real;
BEGIN
s:=b1/(1-q);
writeln('1+1/3+1/(3*3)+...=',s:4:2);
readln;
END.
5
Как Вы сказали- ничего интересного?)) но в данном случае, всё явно и просто. Есть одно "но"(поскольку в задаче не указано количество суммируемых членов), а они действительно не указаны были мною, а зря. Моя ошибка :)). Преподавателя нет, учусь для себя. Спасибо большое за помощь!
Неизвестный
05.06.2009, 12:22
общий
Boriss:
Виноват!
Я не прибавил единицу в первом слагаемом!
Тогда, действительно, результат должен быть 1.49999153245609578486!
Примите мою поправку
Неизвестный
06.06.2009, 12:34
общий
Для начала- Спасибо всем большое за помощь!

Как уже заметили многие, я не указала окончание ряда- он должен заканчиваться на ..1/3 в 8 степени.. поэтому считая с единицей, сделала на const=9; Набрав все ваши коды, я уже чему-то научилась, при чем несколькими способами . Вот мой код программы (я постаралась сделать так, чтобы кроме числа 3 можно было бы вводить с клавиатуры и другие значения), посмотрите, и оцените (если таковые найдутся), мне кажется, вроде всё верно.

const
n=9;
var
i: LongInt;
m: integer;
sum, pred: real;
begin
sum:=1; {Сумма ряда}
pred:=1; {Предыдущий член ряда}
i:=1; {Счетчик}
writeln ('vvedite m');
readln (m);
if (m>=1) then else
writeln ('net reshenija');
while i<10 do begin {Условие окончания - 10 членов ряда просумировано}
sum:=sum+pred/m; {Увеличиваем сумму}
pred:=pred/m; {Текущий член, становится предыдущим}
inc(i); {Увеличиваем количество просуммированных членов на 1}
writeln (sum);
end;
end.
давно
Старший Модератор
31795
6196
06.06.2009, 16:42
общий
Reresana:
if (m>=1) then else
writeln ('net reshenija');

Подумайте над этим участком
Об авторе:
Мне безразлично, что Вы думаете о обо мне, но я рад за Вас - Вы начали думать.

Неизвестный
08.06.2009, 13:18
общий
[q=31795][/q]


ммм.. да-да-да)), это было не то if (m>=1) then else- стоит выделить. Это я с чернового варианта скопировала, не тот код.. хорошо, что сказали.. . Буду внимательней.
Вот:

if (m>=1) then
writeln;
Форма ответа