January 2019

M T W T F S S
 123456
78 910111213
14 151617181920
21222324252627
28293031   

Сообщения

За стиль благодарить

Развернуть метки

No cut tags
Wednesday, November 28th, 2007 01:57 pm
Задачу см. http://taki-net.livejournal.com/335594.html

Правильный ответ на первый вопрос дали почти все в разных вариациях: надо заранее посчитать любым способом (можно очень долго) простые числа до миллиона, вывести в файл, потом включить этот файл в программу в качестве начальных значений элементов массива (их около 72000), дальше организовать просмотр этого массива (хоть двоичным поиском, хоть линейно) и посчитать количество элементов этого массива, больших k и меньших n (он при этом даже не обязан быть сортированным). Вторая программа (с заранее созданным массивом) и была сдана. Кодится (не для любого компилятора) также такое решение: заранее посчитать массив от 1 до 1000000, в котором на i-м месте лежит кол-во простих чисел, меньших i. Программа состоит из одной строчки - вычитания из n-го эл-та массива k-го.

На второй вопрос - ответ под катом.

Жюри подразумевало, что участники должны реализовать решето Эратосфена "честно", не путем деления на все вообще числа меньшие корня (т.е. 1000) - это дает миллиард операций, а у нас в запасе только 200000000, и деление - дорогая операция, а путем правильно сделанного прореживания массива - удаления элементов, кратных простым числам, меньшим тысячи.

Другое возможное решение - тупым псевдоэратосфеном (деление на все до корня из верхней границы) найти все простые до 1000 - это 32000 делений и потом 1000 присваиваний, потом также тупо найти все простые до 1000000 - это около 145 млн. делений и миллион присваиваний потом. Но тут все уже зависит от "цены" деления. Может и не хватить времени.
Wednesday, November 28th, 2007 12:35 pm (UTC)
Вообще, честное решето Эратосфена в виде битовой шкалы из миллиона битов занимает 128Кбайт. А если хранить только нечетные числа (алгоритм прореживания от этого, что характерно, не меняется) то вообще 64К.
А если еще соптимизировать работу с малыми простыми числами (3,5,7) которые жрут больше всего времени, потому что требуют модификации каждого байта решета, то можно еще заметно сэкономить. Решето обрабатывать, естественно, не побайтно, а 32-разрядными словами.

Работу с малыми числами можно делать по нескольку чисел за один проход, держа в регистрах несколько масок,
в которых вздернут каждый третий (пятый, седьмой) бит, и прокручивая эти маски при переходе к следующему 32-разрядному слову на остаток от деления 32 на соответствующее число. Прокручивать надо, естественно, ассемблерной командой rorl.

Я в свое время с подобными вещами развлекался в dos realmode и 16-битном DPMI. Естествено на тех машинах оно работало не секунды. Но на 16Мб памяти (что заметно меньше, чем заявлено в условиях задачИ) выдавало простые числа не до миллиона, а до 128 миллионов. Учитывая, что сейчас процессоры быстрее как минимум на два порядка,
и решето меньше тоже на два порядка, в заявленные 2 секунды можно уложиться.