|
Компьютерный форум OSzone.net » Программирование, базы данных и автоматизация действий » Программирование и базы данных » Java - Помогите с алгоритмом |
|
Java - Помогите с алгоритмом
|
Новый участник Сообщения: 16 |
Профиль | Отправить PM | Цитировать
|
|
Отправлено: 21:53, 25-11-2013 |
Ветеран Сообщения: 1180
|
Профиль | Отправить PM | Цитировать Цитата nastr:
|
|
Отправлено: 13:00, 26-11-2013 | #2 |
Для отключения данного рекламного блока вам необходимо зарегистрироваться или войти с учетной записью социальной сети. Если же вы забыли свой пароль на форуме, то воспользуйтесь данной ссылкой для восстановления пароля. |
Новый участник Сообщения: 16
|
Профиль | Отправить PM | Цитировать Я более точно сформулировал задачу:
Дано: Отсортированный массив, от 0 до N. Задание: Найти оптимальный алгоритм подсчёта суммы значений элементов массива, которые делятся на 3 и на 7 без остатка. Учитывая условие я не нашел более оптимального алгоритма нежели перебор всех элементов: |
Последний раз редактировалось Drongo, 26-11-2013 в 17:20. Причина: тег код # Отправлено: 13:53, 26-11-2013 | #3 |
Новый участник Сообщения: 16
|
Профиль | Отправить PM | Цитировать Можно без массива. Дано N. Найти сумму натуральный чисел, не превосходящих N, которые делятся на 3 и на 7 без остатка.
найти сумма всех чисел не превосходящих N, которые делятся на 3 без остатка. |
Отправлено: 14:54, 26-11-2013 | #4 |
Забанен Сообщения: 5828
|
nastr, выполняйте одну проверку вместо двух, делится ли элемент массива без остатка на 21. Больше тут нечего оптимизировать.
|
|
Отправлено: 15:04, 26-11-2013 | #5 |
Ветеран Сообщения: 1807
|
Профиль | Отправить PM | Цитировать Цитата Leha Ares:
|
|
Отправлено: 15:26, 26-11-2013 | #6 |
Ветеран Сообщения: 1180
|
Профиль | Отправить PM | Цитировать Leha Ares, 7 на 21 не делится
XPEHOMETP, всё корректно nastr, у тебя идеальный алгоритм. Либо это олимпиадная задача и требуется хитрость Хотя... Leha Ares прав: "на 3 и на 7" проще понять как "и на 3, и на 7", чем "на 3 либо на 7" |
Отправлено: 15:26, 26-11-2013 | #7 |
Кот Ти Сообщения: 7318
|
Профиль | Отправить PM | Цитировать Цитата nastr:
Тогда алгоритм весь строится на сумме арифметической прогрессии следующим образом: Шаг 0. Пусть N = 500 (т.е. числа 1 2 3 4... 499 500) Шаг 1. Первый член арифметической прогрессии с шагом в 3 [An=3d] - это 3. Последний член прогрессии = mod(500 / 3) * 3 = 166 * 3 = 498 (используем целочисленное деление). Заодно мы в курсе, что последний член прогрессии имеет номер 166. Шаг 2. Считаем сумму арифметической прогрессии по формуле (в википедии есть) sum = (A1+An)*n/2 = (3 + 498) * 166 / 2 = 41583 Шаг 3. Теперь с семёркой. Тут немного сложнее, т.к. нам надо из суммы исключить числа, делящиеся на 3 Имеем такой ряд: 7 14 28 35 49 56... Т.е. просто An=7d нас не устраивает. Используем хитрость: Шаг 4. Сначала считаем сумму для прогрессии An=7d. 71 член прогрессии равен 497. Сумма = (7 + 497) * 71 / 2 = 17892 Шаг 5. Теперь нужно исключить числа, делящиеся на 21. Считаем сумму прогрессии An = 21d. 23 член прогрессии равен 483. Сумма = (21 + 483) * 23 / 2 = 5796 Шаг 6. Итоговый результат = 41583 + 17892 - 5796 = 53697. Для маленького N такой алгоритм не особо эффективен, но для большого - то, что надо. Для предела в 500 значений, в ассемблере получается 40 инструкций для этого алгоритма и около 6500 инструкций для цикла с делением. Конечно, если у вас массив - это не последовательность натуральных чисел, а просто упорядоченные случайные целые числа больше нуля, то ничего не выйдет, используйте цикл. |
|
Последний раз редактировалось Coutty, 26-11-2013 в 21:06. Отправлено: 18:12, 26-11-2013 | #8 |
Забанен Сообщения: 5828
|
Цитата pva:
|
|
Отправлено: 18:14, 26-11-2013 | #9 |
Новый участник Сообщения: 16
|
Профиль | Отправить PM | Цитировать // declaration decimal N = numericUpDown1.Value, loopTotaSum = 0, loopAmount = 0, prog3Amount, prog3Sum, prog7Amount, prog7Sum, prog21Amount, prog21Sum; System.Diagnostics.Stopwatch st = new System.Diagnostics.Stopwatch(); // Loop st.Start(); for (int i = 1; i <= N; i++) { if (i % 3 == 0 || i % 7 == 0) { loopTotaSum += i; loopAmount++; } } loopTotaSum_textBox.Text = loopTotaSum.ToString(); loopAmount_textBox.Text = loopAmount.ToString(); st.Stop(); loopStopwatch_textBox.Text = st.ElapsedMilliseconds.ToString(); st.Reset(); // Progression st.Start(); prog7Amount = decimal.Truncate(N / 7); prog7Sum = (7 + prog7Amount * 7) * prog7Amount / 2; //Сначала считаем сумму для прогрессии An=7d prog3Amount = decimal.Truncate(N / 3); prog3Sum = (3 + prog3Amount * 3) * prog3Amount / 2; //Считаем сумму арифметической прогрессии An=3d prog21Amount = decimal.Truncate(N / 21); prog21Sum = (21 + prog21Amount * 21) * prog21Amount / 2; //Нужно исключить числа, делящиеся на 21. Считаем сумму прогрессии An = 21d progTotalSum_textBox.Text = Convert.ToString(prog3Sum + prog7Sum - prog21Sum); //Итоговый результат prog3Amount_textBox.Text = Convert.ToString(prog3Amount + prog7Amount - prog21Amount); st.Stop(); progStopwatch_textBox.Text = st.ElapsedMilliseconds.ToString(); |
Отправлено: 16:31, 27-11-2013 | #10 |
Участник сейчас на форуме | Участник вне форума | Автор темы | Сообщение прикреплено |
| |||||
Название темы | Автор | Информация о форуме | Ответов | Последнее сообщение | |
[Ну помогите же человеку, а? :)] Помогите с конкурсом | HTML64 | Тест-форум | 0 | 29-06-2012 10:33 | |
CMD/BAT - [решено] помогите скачал себе этот вирус помогите его разблокировать | orell | Скриптовые языки администрирования Windows | 2 | 05-05-2012 15:45 | |
Разбивка строки в массив из комбинации слов - помогите с алгоритмом, пожалуйста | ANR | Программирование и базы данных | 1 | 25-09-2010 06:43 | |
помогите с алгоритмом решения задачи | bool | Хочу все знать | 2 | 14-06-2008 18:43 | |
Помогите с алгоритмом или исходником двумерного отсечения отрезка. | [mzd] | Программирование и базы данных | 2 | 04-09-2005 20:31 |
|