HeNeos blog

Josue H. @ JP Morgan Chase

HeNeos

← Back to all posts

Project Euler 496

June 16, 2024

#project-euler#algorithms#geometry

I have so much fun with this problem maybe, because it's about euclidean geometry. I think the easiest part is to reach to some conclusions finding similarities and applying some geometry theorems, then the boring part is just the computation. Anyway, I think this will be a good excuse to draw some triangles.

Statement

Given an integer sided triangle ABCABC:

Let II be the incenter of ABCABC.

Let DD be the intersection between the line AIAI and the circumcircle of ABCABC (A≠D)(A \neq D).

We define F(L)F(L) as the sum of BCBC for the triangles ABCABC that satisfy AC=DIAC = DI and BC≤LBC \leq L.

For example, F(15)=45F(15) = 45 because the triangles ABCABC with (BC,AC,AB)=(6,4,5),(12,8,10),(12,9,7),(15,9,16)(BC, AC, AB) = (6, 4, 5), (12, 8, 10), (12, 9, 7), (15, 9, 16) satisfy the conditions.

Find F(109)F(10^{9}).

Solution

As always, when you have a triangle and circumcircle, you can start thinking about cyclyc quadrilaterals, actually the point DD is a good point to start drawing a cyclic quadrilateral.

cyclic quadrilateral

then, drawing the bisector for ∠ACB\angle ACB:

cyclic quadrilateral

finally, just completing angles:

cyclic quadrilateral

Applying Ptolemy's theorem:

xz+x2=x(x+z)=y2xz + x^{2} = x(x+z) = y^{2}

Writing x=m−z2x = \frac{m-z}{2}:

m2=2y2+z2m^{2}=2y^{2}+z^{2}

this problem is similar to generate pythagorean triplets, the only remaining step is to find the upper bound for mm.

m<2y+zz<x+ym<y(2+2)m < \sqrt{2}y+z\\ z < x+y\\ m < y(2+\sqrt{2})

Code

#include <bits/stdc++.h>
using namespace std;
using ll = long long;
#define N 1000000000

int main() {
  int n;
  cin >> n;
  if (n == -1)
    n = N;
  n = min(n, N);
  ll ans = 0;
  for (int u = 1; 1LL * u * u < 3.42 * n; u++) {
    for (int v = 1; v < u && 1LL * u * v <= n; v++) {
      if (1LL * u * u + 1LL * v * v > 3.42 * n)
        break;
      if (__gcd(u, v) == 1 and (u % 2 == 0 or v % 2 == 0)) {
        ll m = 1LL * u * u + 1LL * v * v;
        ll double_a = 2LL * u * v;
        ll c = 1LL * u * u - 1LL * v * v;
        if (c > double_a)
          swap(c, double_a);
        if (double_a % 2 != 0) {
          m *= 2;
          c *= 2;
          double_a *= 2;
        }
        if (5 * c >= 3 * m or double_a > 2 * n)
          continue;
        int a = double_a / 2;
        int b = (m - c) / 2;
        int cnt = n / a;
        ans += (1LL * (cnt + 1) * cnt / 2) * a;
      }
    }
  }
  cout << ans << '\n';
  return 0;
}