Задача: Пусть [latex] x_{1}=x_{2}=x_{3}=1 [/latex];
[latex] x_{i}=x_{i-1}+x_{i-3} [/latex]; [latex] i=4, 5, [/latex]…Вычислить [latex] \sum_{i=1}^{100}{\frac{x_{i}}{2^{i}}} [/latex]
Тесты:
n | result |
-1 | error |
0 | error |
1 | 0.5 |
2 | 0.75 |
3 | 0.875 |
4 | 1 |
5 | 1,09375 |
12 | 1.305908 |
100 | 1.333333 |
Код программы:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 |
#include <stdio.h> int main() { // рабочие переменные double s = 0; int i, n ; double b, x, xPrev = 0, xPrev2 = 0, xPrev3 = 0; int k; if( scanf("%d", &n) <= 0 ) { printf("error: missing n\n" ); return 0; } if( n <= 0 ) { printf("error: out of range: n=%d\n", n); return 0; } // основной цикл сравнения for( i = 1, b = 2; i <= n; i++, b *= 2 ) { if( i > 3 ) xPrev3 = xPrev2; if( i > 2 ) xPrev2 = xPrev; if( i > 1 ) xPrev = x; if( i < 4 ) { x = 1; } else { x = xPrev + xPrev3; } s += x / b; } // вывод результата printf("result: %lf\n", s ); return 0; } |
Код программы на языке Java:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 |
import java.util.*; import java.lang.*; import java.io.*; class SumApp { public static Integer scanInteger( Scanner in ) { return ( ( in.hasNextInt() ) ? in.nextInt() : null ); } public static void main( String[] args ) { // рабочие переменные Integer n = null; int i; double s = 0; double b, x = 0, xPrev = 0, xPrev2 = 0, xPrev3 = 0; Scanner in = new Scanner(System.in); n = scanInteger( in ); in.close(); if( n == null || n <= 0 ) { System.err.printf("error: missing or out of range: n=%d\n", n); return; } // основной цикл сравнения for( i = 1, b = 2; i <= n; i++, b *= 2 ) { if( i > 3 ) { xPrev3 = xPrev2; } if( i > 2 ) { xPrev2 = xPrev; } if( i > 1 ) { xPrev = x; } if( i < 4 ) { x = 1; } else { x = xPrev + xPrev3; } s += x / b; } // вывод результата System.out.printf("result: %f\n", s ); } } |
Ссылка: https://ideone.com/NVdBlc
План программы:
- Назначение рабочих переменных
- Проверка ввода n
- Основной цикл сравнения для получения нужного значения переменных
- Цикл вычисления
- Вывод результата
Программа выполняет суммирование в цикле согласно заданной формуле. Задаётся только число итераций, а слоагемое вычисляется согласно формуле.
Ссылка на ideone.com: http://ideone.com/Yy8e5l
Для начала неплохо. Ошибки писать не буду. Сначала сделайте тесты для разных n. Сначала небольших. Чтобы можно было вычислить вручную. Например, если n взять не 100, а скажем 4, то программа должна выдать 1/2 + 1/4 + 1/8 + 2/16 = 16/16 = 1. А для n=5 добавится ещё 3/32 и ответом будет… сами сосчитайте.
Кстати, в числителе известная последовательность коров Нараяны
Теперь можно проверять:
— Меток нет.
— Вложенные циклы здесь точно ненужны. Из Вашего пояснения я даже предположить не могу, в чём состоит идея алгоритма.
— Вместо тестов сплошная халтура. Ну как у Вас получается 0.25 для n=1? В условии написано х1=1. Разделили на 2 получили 0.5. СЧИТАЙТЕ ТЕСТЫ НА БУМАГЕ ИЛИ В УМЕ!
По программе. Алгоритм у Вас очень простой. Есть 4 переменные. Три из них равны 1. Четвёртая вычисляется как сумма первой и третьей. После этого все значения сдвигаем и снова считаем сумму. Это числитель.
Знаменатель вначале равен 2. Потом удваивается на каждом шаге.
Остаётся накапливать в сумматоре частное от деления числителя на знаменатель.
Если с вычислением числителя не всё понятно, то стоит посмотреть идею «элегантного решения» вычисления чисел Фибоначчи. Там всё как у Вас только используются два предыдущих числа, а у Вас их три.
Совсем мелкое замечание.
А100 — это задача №100 в задачнике Абрамова. Т.е. буква А кириллическая (русская или украинская раскладка). Вы набираете латинскую A. На вид неотличимо, но поисковик не находит Вашего решения.
Лучше набирать А100 не в английской раскладке, а в русской или украинской. Тогда читателям легче будет находить Вашу работу.
Извините за халтуру, не успевал проверить.
Проблема была в баге в цикле расчёта степени 2. Исправил.
Вместо вложенного цикла использовал pow.
А зачем pow? Если завести переменную p и каждый раз её удваивать (р *= 2), то степень двойки в ней будет накапливаться сама. Вы так уже делали однажды (кажется и для факториала тоже).
Лучше это исправить.
Зачтено.
Только освободитесь от pow()
Вы были правы, за каждый шаг происходит умножение на 2.
Уже заменил.
Формулы не отображаются. Что-то случилось?
Да, я попробовал все варианты написания, но формула все равно не хочет показываться.
Максим, у Вас не возникло желания упростить код, глядя на него «с высоты прожитых лет»? Ведь задача решается всего в несколько строк.
— У Java варианта серьёзные проблемы с анализом вводимых данных. У вас две проверки подряд на n <= 0 с разными действиями и return после первого. - Если решили сообщать об ошибках, то для этого следует использовать cerr (C++) и Sisten.err (Java).
Спасибо за замечание, проверка была на n была действительно лишняя, на самом деле я хотел проверить на отсутствие ввода n отдельно от его значения. Теперь я исправил, однако для выявления случая когда n не введен вообще ( ScanInt возвращает null ) мне пришлось изменить тип на Integer, затем я объединил проверку на не введенное и неправильное n и вывожу сообщение об ошибке через System.err . Замечу, что в консоли Windows сообщение об ошибке выводится, а в Ideone — нет. Очевидно, Ideone не способен читать то, что выводится в поток ошибок. Собственно, я изначально выводил сообщения об ошибках также в StdOut из-за этого св-ва Ideone .
Java версия засчитана, 10 баллов!