Я делаю решение этой проблемы из Задача Эйлера Project 513, Интегральная медиана:
ABC является интегральным односторонним треугольником со сторонами a≤b≤c. mc - медиана соединяющий C и середину AB. F (n) - это число таких треугольники с c≤n, для которых mc также имеет целую длину. F (10) = 3 и F (50) = 165.
Найти F (100000).
Анализ:
-
a <= b <= c <= n == 100000
- ABC - это треугольник, поэтому он должен:
abs(a-b) < c < a+b
-
Mc = sqrt(2 * a^2+ 2 * b^2 - c^2) / 2
wikipedia -
Mc
является целым числом, поэтому2 * a^2+ 2 * b^2 - c^2
должно быть идеальным квадратом и делиться на 4.
Код:
#include <stdio.h>
#include <math.h>
#define N 100000
#define MAX(a,b) (((a)>(b))?(a):(b))
void main(){
unsigned long int count = 0;
unsigned long int a,b,c;
double mc;
for (a = 1; a <= N; a++) {
printf("%lu\n", a);
for (b = a; b <= N; b++)
for (c = MAX(b, abs(b-a)); c <=N && c < a+b; c++){
mc = sqrt(2 *a *a + 2 * b * b - c * c)/2.0;
if (mc-(unsigned long)mc == 0)
count++;
}
}
printf("\ncpt == %lu\n", count);
}
Вопросы:
Он отлично подходит для небольших n
, но сложность решения слишком высока, я полагаю, что это O(n^3)
(я ошибаюсь?), который займет несколько дней для n = 100000
.
Как я могу улучшить это с математическим или алгоритмическим способом?
Обновление
Я получил эти предложения:
- Вычисление мощности
a
вне контуровb
/c
и мощностиb
вне циклаc
. Это немного улучшило производительность. -
c
не может быть нечетным. тоa
иb
должны иметь одинаковую четность. Это улучшило производительность в 4 раза. - Использование потоков для разделения работы на многих ядрах. Он может улучшиться в несколько раз ближе к числу ядер.
- Математическое решение, размещенное в math.stackexchange. Он претендует на
O(N^5/2)
для основного решения и может достичьO(N^2)
с помощьюO(N^2)
памяти. Я еще не тестировал его.