All Euler problems
Project Euler

Angular Bisector and Tangent

Given an integer-sided triangle ABC with BC <= AC <= AB, let: k be the angular bisector of angle ACB, m be the tangent at C to the circumscribed circle of ABC, n be the line through B parallel to m...

Source sync Apr 19, 2026
Problem #0296
Level Level 18
Solved By 776
Languages C++, Python
Answer 1137208419
Length 356 words
geometrynumber_theoryanalytic_math

Problem Statement

This archive keeps the full statement, math, and original media on the page.

Given is an integer sided triangle \(ABC\) with \(BC \le AC \le AB\).

\(k\) is the angular bisector of angle \(ACB\).

\(m\) is the tangent at \(C\) to the circumscribed circle of \(ABC\).

\(n\) is a line parallel to \(m\) through \(B\).

The intersection of \(n\) and \(k\) is called \(E\).

PIC

How many triangles \(ABC\) with a perimeter not exceeding \(100\,000\) exist such that \(BE\) has integral length?

Problem 296: Angular Bisector and Tangent

Mathematical Foundation

Theorem 1 (Formula for BEBE). Let a=BCa = BC, b=ACb = AC, c=ABc = AB with abca \leq b \leq c. Then

BE=caa+b.BE = \frac{c \cdot a}{a + b}.

Proof. By the tangent-chord angle theorem (also known as the inscribed angle theorem for tangent lines), the angle between the tangent mm at CC and the chord CACA equals the inscribed angle ABC=β\angle ABC = \beta, and the angle between mm and chord CBCB equals BAC=α\angle BAC = \alpha.

Let γ=ACB\gamma = \angle ACB. The bisector kk bisects γ\gamma, making angles γ/2\gamma/2 with both CACA and CBCB. The line nn through BB is parallel to mm.

In triangle BCEBCE, since nmn \parallel m, the angle EBC=\angle EBC = \angle between nn and BCBC equals the angle between mm and BC=αBC = \alpha (alternate interior angles with the transversal BCBC… more precisely, corresponding angles via the parallel). The bisector kk from CC makes angle γ/2\gamma/2 with CBCB.

Applying the sine rule in triangle BCEBCE:

BEsin(γ/2)=BCsin(BEC).\frac{BE}{\sin(\gamma/2)} = \frac{BC}{\sin(\angle BEC)}.

Since the angles of triangle BCEBCE sum to π\pi, and using EBC=α\angle EBC = \alpha, BCE=γ/2\angle BCE = \gamma/2, we get BEC=παγ/2\angle BEC = \pi - \alpha - \gamma/2. By the sine rule in the original triangle, asinα=bsinβ=csinγ\frac{a}{\sin \alpha} = \frac{b}{\sin \beta} = \frac{c}{\sin \gamma}, and after algebraic manipulation (using α+β+γ=π\alpha + \beta + \gamma = \pi and the identity sinγ=2sin(γ/2)cos(γ/2)\sin \gamma = 2 \sin(\gamma/2)\cos(\gamma/2)), one obtains:

BE=caa+b.BE = \frac{ca}{a + b}. \quad \square

Theorem 2 (Integrality Condition). Let g=gcd(a,b)g = \gcd(a, b), a=gaa = g a', b=gbb = g b' with gcd(a,b)=1\gcd(a', b') = 1. Then BEZBE \in \mathbb{Z} if and only if (a+b)c(a' + b') \mid c.

Proof. We have BE=caa+b=cgag(a+b)=caa+bBE = \frac{ca}{a+b} = \frac{c \cdot ga'}{g(a'+b')} = \frac{ca'}{a'+b'}. Since gcd(a,b)=1\gcd(a', b') = 1, we have gcd(a,a+b)=gcd(a,b)=1\gcd(a', a'+b') = \gcd(a', b') = 1. Therefore (a+b)ca(a'+b') \mid c a' if and only if (a+b)c(a'+b') \mid c. \square

Lemma 1 (Parametric Constraints). Writing c=k(a+b)c = k(a'+b') for some positive integer kk, the constraints are:

  1. Ordering: aba \leq b gives aba' \leq b'; bcb \leq c gives gbk(a+b)gb' \leq k(a'+b').
  2. Triangle inequality: a+b>ca + b > c gives g(a+b)>k(a+b)g(a'+b') > k(a'+b'), hence k<gk < g.
  3. Perimeter: (g+k)(a+b)100,000(g+k)(a'+b') \leq 100{,}000.

Proof. Substituting a=gaa = ga', b=gbb = gb', c=k(a+b)c = k(a'+b'):

  • ab    aba \leq b \iff a' \leq b' (since g>0g > 0).
  • bc    gbk(a+b)b \leq c \iff gb' \leq k(a'+b'), i.e., kgb/(a+b)k \geq \lceil gb'/(a'+b') \rceil.
  • a+b>c    g(a+b)>k(a+b)    g>ka + b > c \iff g(a'+b') > k(a'+b') \iff g > k.
  • Perimeter =ga+gb+k(a+b)=(g+k)(a+b)100,000= ga' + gb' + k(a'+b') = (g+k)(a'+b') \leq 100{,}000. \square

Editorial

Triangle ABC with integer sides a=BC <= b=AC <= c=AB, perimeter <= 100000. BE = ca / (a+b) must be a positive integer. With g = gcd(a,b), a = ga’, b = gb’, gcd(a’,b’)=1: BE = ca’/(a’+b’), so (a’+b’) | c, i.e., c = k*(a’+b’). Constraints: a’ <= b’ (from a <= b) k >= ceil(gb’/(a’+b’)) (from b <= c) k < g (from triangle inequality a+b > c) (g+k)(a’+b’) <= P (perimeter). We enumerate coprime pairs (a’, b’) with 1 <= a’ <= b’. Finally, iterate over each g: k ranges from ceil(g*b’/s) to min(g-1, floor(P/s) - g).

Pseudocode

Enumerate coprime pairs (a', b') with 1 <= a' <= b'
For each g: k ranges from ceil(g*b'/s) to min(g-1, floor(P/s) - g)

Complexity Analysis

  • Time: O ⁣(1abgcd(a,b)=1Pa+b)=O(PH)O\!\left(\sum_{\substack{1 \leq a' \leq b' \\ \gcd(a',b')=1}} \frac{P}{a'+b'}\right) = O(P \cdot H) where H=s=2Pϕpairs(s)sH = \sum_{s=2}^{P} \frac{\phi_{\text{pairs}}(s)}{s} and ϕpairs(s)\phi_{\text{pairs}}(s) counts coprime pairs summing to ss. By standard estimates this is O(PlogP)O(P \log P).
  • Space: O(1)O(1) working memory (no auxiliary data structures beyond loop variables).

Answer

1137208419\boxed{1137208419}

Code

Each problem page includes the exact C++ and Python source files from the local archive.

C++ project_euler/problem_296/solution.cpp
#include <bits/stdc++.h>
using namespace std;

// Problem 296: Angular Bisector and Tangent
//
// Triangle ABC with integer sides a=BC <= b=AC <= c=AB, perimeter <= 100000.
// BE = c*a / (a+b) must be a positive integer.
//
// Let g = gcd(a,b), a = g*a', b = g*b', gcd(a',b')=1.
// Then BE = c*a'/(a'+b'), and since gcd(a',a'+b')=1, we need (a'+b') | c.
// So c = k*(a'+b') for positive integer k.
//
// Constraints:
//   a <= b:          a' <= b'
//   b <= c:          g*b' <= k*(a'+b')  =>  k >= ceil(g*b'/(a'+b'))
//   a+b > c:         g*(a'+b') > k*(a'+b')  =>  k < g
//   perimeter <= P:  (g+k)*(a'+b') <= P

int main(){
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);

    const long long P = 100000;
    long long count = 0;

    // Iterate over coprime (a', b') with 1 <= a' <= b'
    // s = a' + b', s ranges from 2 (a'=b'=1) upward
    // Need (g+k)*s <= P, g >= 2 (since k >= 1, k < g => g >= 2), so s <= P/2

    for (long long bp = 1; bp * 2 + 1 <= P; bp++) {
        // a' ranges from 1 to b'
        for (long long ap = 1; ap <= bp; ap++) {
            if (__gcd(ap, bp) != 1) continue;

            long long s = ap + bp;
            // g ranges from 2 to floor(P/s) - 1 (need k >= 1, so g+1 <= P/s => g <= P/s - 1)
            // Also k < g and k >= ceil(g*b'/s)
            long long max_gs = P / s; // (g+k)*s <= P, g+k <= P/s

            for (long long g = 2; g <= max_gs - 1; g++) {
                // k >= ceil(g*b'/s), k < g, g+k <= P/s => k <= P/s - g
                long long k_min = (g * bp + s - 1) / s; // ceil(g*bp/s)
                long long k_max = min(g - 1, max_gs - g);

                if (k_min > k_max) continue;
                count += k_max - k_min + 1;
            }
        }
    }

    cout << count << endl;
    return 0;
}