Это продолжение массивов Count, которые создают уникальные наборы . Существенным отличием является определение уникальности.
Рассмотрим массив A
длины n
. Массив содержит только натуральные числа. Например A = (1,1,2,2)
. Определим f(A)
как множество сумм всех непустых непрерывных подмассивов A
. В этом случае f(A) = {1,2,3,4,5,6}
. Шаги для производства f(A)
следующие:
Подмассивы A
есть (1), (1), (2), (2), (1,1), (1,2), (2,2), (1,1,2), (1,2,2), (1,1,2,2)
. Их соответствующие суммы 1,1,2,2,2,3,4,4,5,6
. Таким образом, набор, который вы получаете из этого списка {1,2,3,4,5,6}
.
Мы называем массив A
уникальным, если нет другого массива B
такой же длины f(A) = f(B)
, кроме массива в A
обратном порядке. Как пример, f((1,2,3)) = f((3,2,1)) = {1,2,3,5,6}
но нет другого массива длины, 3
который производит тот же набор сумм.
задача
Задача для заданного n
и s
состоит в том, чтобы подсчитать количество уникальных массивов этой длины. Вы можете предположить, что s
между 1
и 9
. Вам нужно только посчитать массивы, где элементы являются либо заданным целым числом, s
либо s+1
. Например, если s=1
подсчитываемые вами массивы содержат только 1
и 2
. Однако определение уникальности относится к любому другому массиву такой же длины. Как конкретный пример не[1, 2, 2, 2]
является уникальным, поскольку он дает тот же набор сумм, что и .[1, 1, 2, 3]
Вы должны рассчитывать как обратную сторону массива, так и сам массив (если, конечно, массив не является палиндромом).
Примеры
s = 1
ответы для n = 2,3,4,5,6,7,8,9:
4, 3, 3, 4, 4, 5, 5, 6
Для s = 1
, уникальные массивы длины 4 являются
(1, 1, 1, 1)
(2, 1, 1, 2)
(2, 2, 2, 2)
s = 2
ответы для n = 2,3,4,5,6,7,8,9:
4, 8, 16, 32, 46, 69, 121, 177
Пример массива, который не уникален с s = 2
:
(3, 2, 2, 3, 3, 3).
Это имеет тот же набор сумм, что и оба: (3, 2, 2, 2, 4, 3)
и (3, 2, 2, 4, 2, 3)
.
s = 8
ответы для n = 2,3,4,5,6,7,8,9:
4, 8, 16, 32, 64, 120, 244, 472
Гол
Для данного n
, ваш код должен выводить ответ для всех значений s
от 1
до 9
. Ваша оценка - это наибольшее значение, n
для которого это завершается за одну минуту.
тестирование
Мне нужно будет запустить ваш код на моей машине с Ubuntu, поэтому, пожалуйста, включите как можно более подробные инструкции по компиляции и запуску вашего кода.
Leaderboard
- Кристиан Сиверс из Хаскелла, n = 13 (42 секунды)
s
? Что это представляет?Ответы:
Haskell
orig
Функция создает все списки длиныn
с записямиs
илиs+1
, держит их , если они приходят , прежде чем их реверс, вычисляет их подсписокsums
и помещает те в карте , которая также запоминает первый элемент списка. Когда один и тот же набор сумм встречается более одного раза, первый элемент заменяется наNothing
, поэтому мы знаем, что нам не нужно искать другие способы получения этих сумм.В
construct
функции ищет списки заданной длиной и дано начальное значение , которые имеют заданный набор Подсписок сумм. Его рекурсивная частьconstr
следует по сути той же логике, что и эта , но имеет дополнительный аргумент, дающий сумму, которую должны иметь оставшиеся записи списка. Это позволяет рано останавливаться, когда даже самые маленькие возможные значения слишком велики, чтобы получить эту сумму, что дало значительное улучшение производительности. Дальнейшие большие улучшения были получены путем перемещения этого теста на более раннее место (версия 2) и замены списка текущих сумм наVector
(версия 3 (не работает) и 4 (с дополнительной строгостью)). В последней версии тест на членство в наборе устанавливается с помощью таблицы поиска и добавляет еще больше строгости и распараллеливания.Когда
construct
найден список, в котором указаны суммы подсписков и он меньше его обратного, он может его вернуть, но мы на самом деле не заинтересованы в нем. Было бы почти достаточно просто вернуться,()
чтобы указать на его существование, но нам нужно знать, нужно ли нам считать его дважды (потому что это не палиндром, и мы никогда не справимся с его обратным). Таким образом, мы помещаем 1 или 2weight
в список результатов.Функция
count
объединяет эти части. Для каждого набора сумм подсписков (поступающих изorig
), который является уникальным среди списков, содержащих толькоs
иs+1
, он вызываетvalue
, который вызываетconstruct
и, посредствомuniqueval
, проверяет, есть ли только один результат. Если это так, то это вес, который мы должны посчитать, иначе набор сумм не будет уникальным и возвращается ноль. Обратите внимание, что из-за лени,construct
остановится, когда найдет два результата.В
main
функции ручки ввода - вывода и петляs
от 1 до 9.Компиляция и запуск
На Debian нужны пакеты
ghc
,libghc-vector-dev
иlibghc-parallel-dev
. Сохраните программу в файлprog.hs
и скомпилируйте егоghc -threaded -feager-blackholing -O2 -o prog prog.hs
. Запустите с./prog <n> +RTS -N
где<n>
длина массива, для которого мы хотим подсчитать уникальные массивы.источник