Рассмотрим треугольник ABC, где каждая сторона имеет целочисленную длину ( целочисленный треугольник ). Определить медиану из ABC быть отрезок от вершины до середины противоположной стороны. На рисунке ниже сегменты красной линии представляют медианы. Обратите внимание, что любой данный треугольник имеет три медианы.
Пусть n будет некоторым положительным целым числом. Сколько невырожденных интегральных треугольников с длиной каждой стороны, меньшей или равной n, имеют хотя бы одну интегральную медиану?
Вызов
Напишите программу для вычисления количества интегральных треугольников с хотя бы одной интегральной медианой для данной максимальной длины стороны n . Порядок длин сторон не имеет значения, т.е. <6,6,5> представляет тот же треугольник, что и <5,6,6>, и должен учитываться только один раз. Исключите вырожденные треугольники, такие как <1,2,3>.
счет
Наибольшее число n, для которого ваша программа может сгенерировать количество треугольников за 60 секунд на моей машине, - это ваш результат. Программа с наибольшим количеством очков выигрывает. Моя машина Sony Vaio SVF14A16CLB, Intel Core i5, 8 ГБ оперативной памяти.
Примеры
Пусть Т ( Н ) быть программой с входным N .
T(1) = 0
T(6) = 1
T(20) = 27
T(22) = 34
Обратите внимание, что T (1) = T (2) = T (3) = T (4) = T (5) = 0, потому что никакая комбинация целых сторон не даст интегральной медианы. Однако, как только мы дойдем до 6, мы увидим, что одна из медиан треугольника <5,5,6> равна 4, поэтому T (6) = 1.
Также обратите внимание, что T (22) является первым значением, при котором двойной счет становится проблемой: треугольник <16,18,22> имеет медианы 13 и 17 (и 2sqrt (85)).
Вычисление медиан
Медианы треугольника можно рассчитать по следующим формулам:
Current top score: Sp3000 - 7000 points - C
источник
Ответы:
C, грубая сила - n = 6080
Это скорее базовый уровень, чем серьезный соперник, но, по крайней мере, все должно начаться.
n = 6080 - это столько же, сколько я получил за минуту работы на моем собственном компьютере, то есть MacBook Pro с Intel Core i5. Результат, который я получил для этого значения:
Кодекс чисто грубая сила. Он перечисляет все треугольники в пределах ограничения по размеру и проверяет условие:
источник
lrintf()
или(int)roundf()
вместо добавления 0,5f и использования усечения по умолчанию. Однако иногда вам нужно использовать-ffast-math
его для компиляции в однуcvtss2si
инструкцию. gcc inlinelrintf()
иsqrtf
only only-fno-math-errno
, так что вы получите эффективный asm: godbolt.org/g/E3hncQ . (Я использовал,-march=ivybridge
потому что это процессор ОП). С помощью-ffast-math
clang превращает sqrt в итерацию rsqrt + Ньютона; ИДК, если это победа.roundf
. Используйте(int)nearbyintf()
iflrintf()
, не встроенный, потому что он использует текущий режим округления вместо определенного странного. stackoverflow.com/questions/37620659/…С, около
66506900Я не очень часто использую C, но с учетом продолжающейся арифметики это казалось хорошим выбором языка. Основной алгоритм - грубая сила, как ответ @ RetoKoradi , но с несколькими простыми оптимизациями. Я не уверен, что наши значения сопоставимы, потому что компьютер @ RetoKoradi, кажется, быстрее, чем мой.
Основная оптимизация - полностью обойти
% 4
проверку. Целочисленный квадратn*n
равен 0 или 1 по модулю 4, в зависимости от тогоn
, равен ли он 0 или 1 по модулю 2. Таким образом, мы можем взглянуть на все возможности для(x, y, z) % 2
:Удобно, что нужно рассмотреть только два случая:
(0, 0, 0)
и(1, 1, 0)
, учитывая первые две стороныa, b
, соответствует третьей стороне,c
имеющей четностьa^b
:a^b
имеет тот же паритетa-b
, что и вместо поискаc = a-b+1
и увеличения на 1 с, это позволяет нам искатьc = a-b+2
и подниматься на 2 с.Другая оптимизация связана с тем, что в данном
(1, 1, 0)
случае нам нужно вызывать is_square только один раз, так как работает только одна перестановка. Это особый случай в коде путем развертывания поиска.Другая включенная оптимизация - просто быстрый сбой в
is_square
функции.Компиляция была сделана с
-std=c99 -O3
.(Спасибо @RetoKoradi за указание на то, что
0.5
in_square должен быть0.5f
во избежание двойного преобразования.)источник
0.5f
вместо0.5
вis_square()
.0.5
является константой типаdouble
, так что выражение произведет двойное значение при добавлении0.5
, в том числе преобразования типа изfloat
кdouble
для другого термина.f
, на самом деле.Феликс, неизвестно
В основном это порт ответа C, но он быстрее, чем проверенный с
clang -O3
иicc -O3
. Феликс и Ним - это буквально два языка, которые я знаю, которые могут превзойти C и C ++ в тестах. Я работаю над параллельной версией, но это будет немного, пока она не закончится, поэтому я решил опубликовать это заранее.Я также поставил «неизвестно», потому что мой компьютер не обязательно самый быстрый на земле ...
Команда используется для сборки:
Сгенерированный C ++ довольно интересен для просмотра:
источник
C # (около 11000?)
n
принимается в качестве аргумента командной строки.объяснение
источник
n=5000
составляет 67 секунд для ответа Рето Коради, 48 секунд для ответа Sp3000 и 13 секунд для моего ответа.C, n = 3030 здесь
Результаты:
приведенный выше код будет переводом в C ответа Axiom (если мы не будем считать функцию isq ()).
Мой компилятор не связывает функцию, другие используют sqrtf () ... здесь нет функции sqrt для float ... Они уверены, что sqrtf это стандартная функция C?
источник
APL NARS, n =
239282 за 59 секунд(я пишу один аксиомный ответ в APL):
источник
Аксиома, n = 269 через 59 с
Если a, b, cx - длина сторон одного треугольника стороны максимальной длины n ...
Мы бы знали, что m: = sqrt ((2 * (a ^ 2 + b ^ 2) -cx ^ 2) / 4)
Как сказал Питер Тейлор, 4 | (2 * (a ^ 2 + b ^ 2) -cx ^ 2) и потому что 2 | 2 * (a ^ 2 + b ^ 2), чем 2 | cx ^ 2 => cx = 2 * с. Так с 1 будет
a и b должны иметь одинаковую четность, чтобы мы могли написать b как функцию
чем у нас это
поэтому (1) можно переписать, см. (2) (3) (4) как:
где
Результаты
источник
VBA 15 000 за десять секунд!
Я ожидал намного меньше после этих других постов. На Intel 7 с 16 ГБ оперативной памяти я получаю 13-15 000 за десять секунд. На Pentium с 4 ГБ ОЗУ я получаю 5-7000 за ДЕСЯТЬ секунд. Код ниже. Вот последний результат на Pentium
Он получил треугольник со сторонами 240, 239, 31 и средой 121. Количество носителей составляет 7 371.
источник