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 (AD)(A \neq D).

We define F(L)F(L) as the sum of BCBC for the triangles ABCABC that satisfy AC=DIAC = DI and BCLBC \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=mz2x = \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;
}