![]() |
1. Заголовок темы должен быть информативным. В противном случае тема удаляется ...
2. Все тексты программ должны помещаться в теги [code=pas] ... [/code].
3. Прежде чем задавать вопрос, см. "FAQ", если там не нашли ответа, воспользуйтесь ПОИСКОМ, возможно такую задачу уже решали!
4. Не предлагайте свои решения на других языках, кроме Паскаля (исключение - только с согласия модератора).
5. НЕ используйте форум для личного общения, все что не относится к обсуждению темы - на PM!
6. Одна тема - один вопрос (задача)
7. Проверяйте программы перед тем, как разместить их на форуме!!!
8. Спрашивайте и отвечайте четко и по существу!!!
![]() ![]() |
![]() |
Unconnected |
![]()
Сообщение
#1
|
![]() mea culpa ![]() ![]() ![]() ![]() ![]() Группа: Пользователи Сообщений: 1 372 Пол: Мужской Реальное имя: Николай Репутация: ![]() ![]() ![]() |
Привет всем
![]() Пробую решить олимпиадную задачку (конечно, с уже давно окончившейся олимпиады )), про последовательность (битов) Кеане - кто этот Кеане, я не знаю, и Вики с гуглом тоже. Формулировка такая: Цитата Последовательность Кеане (Время: 1 сек. Память: 16 Мб Сложность: 57%) Бесконечная последовательность битов, предложенная Кеане, равна 001001110001001110110110001… и формируется следующим алгоритмом: вначале записывается 0, потом 001, далее 001001110, то есть, для получения следующего члена, предыдущий записывается дважды, а справа приписывается его отрицание. Элементы этого ряда являются начальными подпоследовательностями Кеане. Требуется написать программу, которая по заданному n определит N-й бит этой последовательности. Входные данные Входной файл INPUT.TXT содержит число N (N <= 10200). Выходные данные В выходной файл OUTPUT.TXT должен содержать найденный бит. Просто генерировать последовательность у меня получается, вот так: {$APPTYPE CONSOLE} (хотя, у меня такое ощущение, что она как-то неправильно генерирует) Проблема в очень большом максимально возможном N. Здесь, видимо нужно использовать длинную арифметику, но я вот не понимаю, в каком месте её использовать. Ну допустим есть строка-последовательность, есть N в виде строки, и что с чем складывать? Кажется, даже строку с последовательностью такой длины получить не получится, и тем более length() от неё. Может, формулу можно вывести для нахождения бита по позиции? Сообщение отредактировано: Unconnected - 5.06.2010 17:22 -------------------- "Знаешь, стыдно - когда не видно, что услышал всё, что слушал.."
|
Cheburashka |
![]()
Сообщение
#2
|
![]() Бывалый ![]() ![]() ![]() Группа: Пользователи Сообщений: 195 Пол: Мужской Реальное имя: Сергей Репутация: ![]() ![]() ![]() |
Генерация может быть и правильная, но проблема не в этом!
ты берешь тип инт64, который сам по себе не может включать 10^200, у него всего 10^18 (может больше, может меньше. Не помню я ![]() Вот и реализовывай длинную арифметику для числа N. Думаю, что с тем, чтобы считать длинное число с файла, проблем не возникнет. Но надо подумать как найти элемент строки с этим номером! Сообщение отредактировано: Сергей Меркурьев - 5.06.2010 17:54 -------------------- ♣♣♣
"Себя великим не считай, гордясь величьем предков, Величья не добудешь ты и золота ценою! Хоть светит на небе луна, но отраженным светом - Чужою славой не живи, не будь второй луною!!!" ♣♣♣ |
volvo |
![]()
Сообщение
#3
|
Гость ![]() |
Unconnected, вот смотри, какой путь я бы избрал (показываю с применением обычной арифметики, с небольшими значениями). Идея - такая.
const Что меня мучает - это уж очень маленькое время задано для таких огромных чисел, времени может не хватить, тем более в случае использования длинной арифметики. Но это пока то, что мне придумалось, может потом наступит прозрение, как решать эту задачу... ![]() P.S. И все-таки, по поводу Цитата кто этот Кеане, я не знаю, и Вики с гуглом тоже - это Mephisto Waltz Sequence |
Lapp |
![]()
Сообщение
#4
|
![]() Уникум ![]() ![]() ![]() ![]() ![]() ![]() ![]() Группа: Модераторы Сообщений: 6 823 Пол: Мужской Реальное имя: Лопáрь (Андрей) Репутация: ![]() ![]() ![]() |
[indent]
Вот так выглядит последовательность, сформированная по приведенному тобой правилу: volvo, мне думается, что все не совсем так, и заодно немного проще..0_001_001001110_001001110001001110110110001 (40 бит). Она состоит, как видим, из 4-х членов (я разделил их символами подчеркивания). Нужный нам бит находится в третьем члене, начиная с 0-го; Последовательность, как я ее понял, представляет собой не совокупность членов, а просто один такой член, растущий по приведенному правилу. 0 001 001001110 001001110001001110110110001 Мне кажется, что красмвее и понятнее формулировать так: последовательность получается посредством приписывания САМОЙ СЕБЯ к себе слева и своего отрицания - справа. Легко видеть, что отсюда сразу следуют два положения: 1. значение n-нного бита сохраняется; 2. длина последовательности на каждом шагу выражается степенью тройки. Первый пункт делает вопрос задачи осмысленным. Второй, как мне кажется, дает ключ к решению. Но самого решения у меня пока нет. Сегодня пока занят другими делами, освобожусь - порешаю. -------------------- я - ветер, я северный холодный ветер
я час расставанья, я год возвращенья домой |
volvo |
![]()
Сообщение
#5
|
Гость ![]() |
Да. Не совсем так... Правда. Нужно кое-что добавить:
// после строки: Тогда для любого N > 1 (особый случай N = 1 обрабатывается отдельно, в ветке else основного if-а, который с циклом repeat/until), от 2 до 21 миллиона (больше не проверял, ждать генерации последовательности для сравнения приходится очень долго) программа выдает одинаковый результат при вычислении значения заданного бита и при его извлечении из последовательности. Это достаточный критерий правильности программы? Если указанное изменение не вносить, то при значениях N, являющихся членами вот этой последовательности результат получается некорректным. Update Если имеется в виду, что я не прав в том, что я сначала подставляю нулевой, потом - первый, и так далее члены MW Sequence, а надо сначала сгенерировать i-тый член подходящей длины, и только в нем искать N-ый бит (не обращая внимание на предыдущие i-1 членов последовательности), так еще проще: экономим одно действие, bit_in_seq вычислять не надо, можно просто брать N и работать с ним... Результат еще быстрее вычислится. |
Unconnected |
![]()
Сообщение
#6
|
![]() mea culpa ![]() ![]() ![]() ![]() ![]() Группа: Пользователи Сообщений: 1 372 Пол: Мужской Реальное имя: Николай Репутация: ![]() ![]() ![]() |
Сейчас дорассмотрел наконец код volvo (лето, напряжёнка ) ), для небольших чисел это наверное и будет самый оптимальный вариант (погонял, кстати - string- и calceulated-результаты соответствуют), а вот если взять n=10200 - то я, например, даже не представляю, как находить для него логарифм и т.п. с помощью длинной арифметики. (благодарю за код, познавательно!)
Последовательность состоит из элементарных 001 и 110 (при n>=3). Может, обозначать их нулём и единицей, к примеру? Тогда генерировать меньше будет, и находить быстрее. Lapp, не совсем понял насчёт этих положений. Ну и что с того, что длина выражается степенью тройки? Это как-то поможет в нахождении нужного члена? -------------------- "Знаешь, стыдно - когда не видно, что услышал всё, что слушал.."
|
TarasBer |
![]()
Сообщение
#7
|
![]() Злостный любитель ![]() ![]() ![]() ![]() ![]() Группа: Пользователи Сообщений: 1 755 Пол: Мужской Репутация: ![]() ![]() ![]() |
> n=10^200 - то я, например, даже не представляю, как находить для него логарифм
ln(10)*200 -------------------- |
Lapp |
![]()
Сообщение
#8
|
![]() Уникум ![]() ![]() ![]() ![]() ![]() ![]() ![]() Группа: Модераторы Сообщений: 6 823 Пол: Мужской Реальное имя: Лопáрь (Андрей) Репутация: ![]() ![]() ![]() |
Ну и что с того, что длина выражается степенью тройки? Это как-то поможет в нахождении нужного члена? Так volvo же это как раз и использовал! трихотомия ))-------------------- я - ветер, я северный холодный ветер
я час расставанья, я год возвращенья домой |
![]() ![]() |
![]() |
Текстовая версия | 19.07.2025 13:49 |