| Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
| Форум программистов > Алгоритмы > Вычисление ряда уникальных чисел по формулам |
| Автор: dershokus 12.11.2012, 17:29 |
| Снова здравствуйте Нужно напечатать 1000 неповторяющихся чисел в порядке возрастания из множества M: 1. единица принадлежит к множеству M 2. к множеству M принадлежит число 2*x+1 (х - принадлежит множеству М) 3. к множеству М принадлежит число 3*х+1 (х - принадлежит множеству М) Конечно можно просто посчитать все, отсортировать и вычеркнуть одинаковые и если не достаточно чисел - повторить процесс, но может можно как-то легче? |
| Автор: Фантом 12.11.2012, 19:12 |
| Чего-то в Вашем условии явно не хватает. В его рамках ряд чисел a(n)=2*a(n-1)+1, a(0)=1 будет ответом, но, наверное, хочется получить что-то другое? |
| Автор: Фантом 12.11.2012, 19:35 |
Зависимости рекуррентные, так что это не две прямые. К тому же, насколько я понимаю, никак не возбраняется "переключаться" с одной зависимости на другую. Другое дело, что, как я уже писал, тут явно не хватает какого-то условия. Например, того, что надо напечатать 1000 наименьших неповторяющихся чисел. |
| Автор: dershokus 12.11.2012, 20:58 | ||
да. я написал в порядке возрастания. можно с любого элемента начинать, просто проше всего начинать с 1. Ряд сначала получается 1 3 4 7 9 10... Тоесть мы получаем из 1 элемента - 2. Но если сначала считать первую формулу для 3 а потом для 4 (на первом просчете) а потом второую формулу для них - мы не получим упорядоенный ряд. (реализация на работе, завтра отправлю первые .... много чисел из этого ряда). Если на некотором просчете мы получили N чисел из которых мы должны получить 2*N (по двум формулам), то в 2*N числах могут быть такие, которые меньше чем числа из N. Что-то витьевато выражаюсь, за что извиняюсь |
| Автор: Akina 12.11.2012, 21:46 | ||
|
| Автор: Фантом 12.11.2012, 21:53 | ||||
Мое первое "решение" тоже будет выдавать числа в порядке возрастания. Ну ладно, кажется, я понял, что требуется. Тогда проще просто пройтись по натуральным числам подряд, проверяя, можно ли получить очередное из уже существующих в ряду. Выглядеть это будет примерно так (поскольку я не знаю, на каком языке это нужно реализовывать, написал на Паскале, для описания алгоритма это проще)
Здесь n - счетчик накопившегося количества чисел, размер 10000 взят "с запасом", чтобы наверняка хватило. |
| Автор: dershokus 13.11.2012, 09:05 | ||||
| Akina, Вы не правы. Ваш алгоритм не просчитываем числа из множества. Ряд такой получается:
по вашему алгоритму
|
| Автор: Akina 13.11.2012, 10:56 |
| dershokus, само собой, я же не учитываю ветвления. Но идея может быть использована. Правда, потребуется не два аккумулятора, а динамически расширяемый массив аккумуляторов. Из которого берётся наименьший элемент, печатается, затем на его основе генерится и помещается в массив 2 новых значения, а обработанное значение выбрасывается. |
| Автор: Silent 14.11.2012, 10:43 | ||||
Простейший вариант - взять очередь с приоритетами, в две минуты пишется код:
Ну а если еще чуть подумать, то становится ясно, что это стрельба по воробьям из пушки, и гораздо проще идея, предложенная Фантомом, сделать простой перебор:
Я бы стал сдавать код №2 - проще, быстрее, никакого расхода памяти |
| Автор: Фантом 14.11.2012, 11:31 | ||||
Вы забыли одну важную деталь (учет которой, собственно, и приводит к расходу памяти): по условию, числа 2*x+1 и 3*x+1 принадлежат M в том случае, если x принадлежит M (а не является целым числом, как у Вас). Первое отличие - число 5. Оно, конечно, нечетное, но подходящего для него x не существует. К тому же Ваш вариант (если уж пользоваться измененным условием задачи) можно сильно упростить. Наименьшее общее кратное 2 и 3 равно 6, поэтому код
будет выдавать такой же результат. |
| Автор: Silent 14.11.2012, 12:34 |
| Каюсь, со вариантом №2 просчитался - слишком поверхностно посмотрел Ваш код. Тем не менее, у меня еще есть второй вариант, который №1 |
| Автор: Фантом 14.11.2012, 21:40 |
Это да, но всерьез пользоваться возможностями C++, если явно не оговорено, что это можно, как-то нехорошо. |
| Автор: volatile 15.11.2012, 04:37 | ||
http://codepad.org/FKQFn95I Добавлено через 5 минут и 35 секунд без повторов же надо. это без повторов. Добавлено через 11 минут и 58 секунд оу, сорри. паскакалей не знаем. |
| Автор: Silent 15.11.2012, 08:12 | ||||
я такого пункта от автора топика не увидел, укажите, если я не прав (хотя, конечно, и не сказано про язык реализации). Тогда предлагаю кросс-языковый вариант (предполагаю, что можно использовать хотя бы массивы):
|
| Автор: volatile 15.11.2012, 23:41 | ||
| Вот самый первый, который мне вчера пришел в голову (и самый тупой) вариант на простом массиве. Если в языке больше ничо нет, то прокатит!
http://codepad.org/PVnrqXve |
| Автор: volatile 16.11.2012, 00:00 | ||
Не факт. Может в паскале нет массивов... (точно не могу сказать). В любом случае, массивы использовать нехорошо. Вот (не менее тупой) вариант без массивов:
http://codepad.org/HTEJ7x8F Не знаю, правда, насколько хорошо было использовать цЫклы ? возможно в паскале цЫклов нет... (точно не могу сказать). Добавлено через 8 минут и 2 секунды Ну и модификация последнего алгоритма, с разбиением на столбики. А то, у меня строка не влазила целиком в экран (моник слабоват). Вот здесь циферки в 10 столбиков. http://codepad.org/bnctfc43 Добавлено через 11 минут и 46 секунд Последний вариант, должен быть медленней прочих. Но зато он без специальных возможностей C++, как то: Он без STL алгоритмов! Без контейнеров! И даже без простых массивов! Ну и там можно начать печатать в любом порядке, и с любого элемента, не только 1-го. |