勾股三元组 solutions

09J25101 2025-10-09 13:15:45 2025-10-09 13:23:20

InputA positive integer n.OutputAll ordered positive integer triples (a,b,c),that satisfy 1abcn and a2+b2=c2,sorted in ascending order with a as the first key and b as the second key.\begin{array}{ll} \textbf{Input}&\text{A positive integer }n\text{.}\\ \textbf{Output}&\text{All ordered positive integer triples }(a,b,c)\text{,}\\ &\text{that satisfy }1\le a\le b\le c\le n\text{ and }a^2+b^2=c^2\text{,}\\ &\text{sorted in ascending order with }a\text{ as the first key and }b\text{ as the second key.}\\ \end{array}

算法 1

枚举 a,b,ca,b,c 并判断即可。

时间复杂度为 O(n3)O(n^3),能通过 easy version。

1for a1 to n2for ba to n3for cb to n4if a2+b2=c25print (a,b,c)\begin{array}{ll} 1&\textbf{for }a\gets1\textbf{ to }n\\ 2&\quad\textbf{for }b\gets a\textbf{ to }n\\ 3&\qquad\textbf{for }c\gets b\textbf{ to }n\\ 4&\qquad\quad\textbf{if }a^2+b^2=c^2\\ 5&\qquad\qquad\text{print }(a,b,c) \end{array}

算法 2

枚举 a,ba,b,判断 a2+b2\sqrt{a^2+b^2} 是否为 n\le n 的整数。

这可以变通成判断 c=a2+b2c=\lfloor\sqrt{a^2+b^2}\rfloor 是否满足 cnc\le na2+b2=c2a^2+b^2=c^2

时间复杂度为 O(n2)O(n^2),能通过 medium version。

1for a1 to n2for ba to n3ca2+b24if cn and a2+b2=c25print (a,b,c)\begin{array}{ll} 1&\textbf{for }a\gets1\textbf{ to }n\\ 2&\quad\textbf{for }b\gets a\textbf{ to }n\\ 3&\qquad c\gets\lfloor\sqrt{a^2+b^2}\rfloor\\ 4&\qquad\textbf{if }c\le n\text{ and }a^2+b^2=c^2\\ 5&\qquad\quad\text{print }(a,b,c) \end{array}

算法 3

笔者原初的想法是这样的:

a2+b2=c2a^2+b^2=c^2 变形成 a2=(c+b)(cb)a^2=(c+b)(c-b)

枚举 aa,根据 aa 的质因数分解枚举 a2a^2 的约数 dd,解 {cb=dc+b=a2d\begin{cases}c-b=d\\c+b=\dfrac{a^2}{d}\end{cases} 并判断是否满足 abcna\le b\le c\le n

1,2,,n1,2,\cdots,n 的质因数分解可用欧拉筛预处理,对于每个 aa 还需把 a2a^2 的约数排序。

时间复杂度为 O(i=1nd(i2)logd(i2))=O(nlog2nloglogn)O\left(\sum\limits_{i=1}^n\mathrm{d}(i^2)\log\mathrm{d}(i^2)\right)\color{gray}{=O(n\log^2n\log\log n)},能通过 hard version。

procedure EulerSieve1for i2 to n2if i hasn’t been marked as a composite number3smallestPrimeFactor[i]i4add i to the prime sequence5for each prime j that satisfies jsmallestPrimeFactor[i] and ijn6smallestPrimeFactor[ij]j7mark ij as a composite numberfunction getFactors(a,d)1if a=12add d to the factor sequence3return4vsmallestPrimeFactor[a]cnt05while va do6aavcntcnt+17for i0 to 2cnt8getFactors(a,d)9ddvprocedure mainSolve1run EulerSieve2for a1 to n3clear the factor sequence, run getFactors(a,1)4sort the factor sequence in descending order5for each d in the sorted factor sequence that satisfies d<a6b12(a2dd)c12(a2d+d)7if ab and cn8print (a,b,c)\begin{array}{l} \textbf{procedure}\text{ EulerSieve}\\ \begin{array}{ll} 1&\textbf{for }i\gets2\textbf{ to }n\\ 2&\quad\textbf{if }i\text{ hasn't been marked as a composite number}\\ 3&\qquad\textit{smallestPrimeFactor}[i]\gets i\\ 4&\qquad\text{add }i\text{ to the prime sequence}\\ 5&\textbf{for}\text{ each prime }j\text{ that satisfies }j\le\textit{smallestPrimeFactor}[i]\text{ and }ij\le n\\ 6&\quad\textit{smallestPrimeFactor}[ij]\gets j\\ 7&\quad\text{mark }ij\text{ as a composite number} \end{array}\\ \textbf{function}\text{ getFactors}(a',d)\\ \begin{array}{ll} 1&\textbf{if }a'=1\\ 2&\quad\text{add }d\text{ to the factor sequence}\\ 3&\quad\textbf{return}\\ 4&v\gets\textit{smallestPrimeFactor}[a']\text{, }\textit{cnt}\gets0\\ 5&\textbf{while }v\mid a'\textbf{ do}\\ 6&\quad a'\gets\dfrac{a'}{v}\text{, }\textit{cnt}\gets\textit{cnt}+1\\ 7&\textbf{for }i\gets0\textbf{ to }2\textit{cnt}\\ 8&\quad\text{getFactors}(a',d)\\ 9&\quad d\gets dv \end{array}\\ \textbf{procedure }\text{mainSolve}\\ \begin{array}{ll} 1&\text{run EulerSieve}\\ 2&\textbf{for }a\gets1\textbf{ to }n\\ 3&\quad\text{clear the factor sequence, run getFactors}(a,1)\\ 4&\quad\text{sort the factor sequence in descending order}\\ 5&\quad\textbf{for}\text{ each }d\text{ in the sorted factor sequence that satisfies }d<a\\ 6&\qquad b\gets\dfrac{1}{2}\left(\dfrac{a^2}{d}-d\right)\text{, }c\gets\dfrac{1}{2}\left(\dfrac{a^2}{d}+d\right)\\ 7&\qquad\textbf{if }a\le b\text{ and }c\le n\\ 8&\qquad\quad\text{print }(a,b,c) \end{array} \end{array}

算法 4

大多数同学都通过查阅资料或询问 AI 得到以下做法。

对于 (a,b,c)(a,b,c),记 d=gcd(a,b)d=\gcd(a,b),若 d>1d>1,称它由 (ad,bd,cd)\left(\dfrac{a}{d},\dfrac{b}{d},\dfrac{c}{d}\right) 生成,例如 (6,8,10)(6,8,10)(3,4,5)(3,4,5) 生成。称满足 d=1d=1(a,b,c)(a,b,c) 为本原勾股三元组,考虑枚举它,生成 (ka,kb,kc)(ka,kb,kc)kcnkc\le n)。

下面考察本原勾股三元组 (a,b,c)(a,b,c) 的性质:

首先,a,ba,b 一奇一偶。a,ba,b 不可能均为偶数,而若 a,ba,b 均为奇数,则 c2c^222 的倍数但非 44 的倍数,与 c2c^2 是平方数矛盾。因此,可暂且忽略 a,ba,b 之间的大小关系,设 aa 是偶数,bb 是奇数,显然 cc 是奇数。

考察 a2=(c+b)(cb)a^2=(c+b)(c-b),有 c+b2,cb2\dfrac{c+b}{2},\dfrac{c-b}{2} 是互质的平方数:若不互质,设 gcd(c+b,cb)=2d>2\gcd(c+b,c-b)=2d>2,则 2d2b2d\mid2b,从而 dbd\mid bdcd\mid cdad\mid a,矛盾!c+b2,cb2\dfrac{c+b}{2},\dfrac{c-b}{2} 互质且乘积是平方数 a24\dfrac{a^2}{4},根据质因数分解这两个数是互质的平方数。

c+b=2x2c+b=2x^2cb=2y2c-b=2y^2,满足 gcd(x,y)=1\gcd(x,y)=1,解得

{a=2xyb=x2y2c=x2+y2\begin{cases} a=2xy\\ b=x^2-y^2\\ c=x^2+y^2 \end{cases}

另一方面,考虑枚举 1y<x1\le y<x 满足 gcd(x,y)=1\gcd(x,y)=1x2+y2nx^2+y^2\le n,得到 a,b,ca,b,c。此外,x,yx,y 的奇偶性要不同,否则 b,cb,c 是偶数。目前确有 a2+b2=c2a^2+b^2=c^2,还需证明 gcd(a,b)=1\gcd(a,b)=1:若不然,设 gcd(a,b)=d>1\gcd(a,b)=d>1,则 db=x2y2,c=x2+y2d\mid b=x^2-y^2,c=x^2+y^2dd 是奇数且 d2y2d\mid2y^2,从而 dy2d\mid y^2dx2d\mid x^2,与 x2,y2x^2,y^2x,yx,y 互质矛盾!

综上,我们得以精确地找出勾股数,只不过还需排序。根据算法 3 的思路和参考文章,勾股三元组个数的量级不高于 O(nlog2n)O(n\log^2n)。若直接一起排序,时间复杂度为 O(nlog3n)O(n\log^3n),能通过 hard version。

1for (x2x2<nxx+1)2for (y1y<x and x2+y2nyy+1)3if gcd(x,y)=1 and (xy)mod2=14a=2xyb=x2y2c=x2+y25if a>b6swap a,b7for (k1kcnkk+1)8add (ka,kb,kc) to the answer sequence9sort the answer sequence and print it out\begin{array}{ll} 1&\textbf{for}\text{ (}x\gets2\text{; }x^2<n\text{; }x\gets x+1\text{)}\\ 2&\quad\textbf{for}\text{ (}y\gets1\text{; }y<x\text{ and }x^2+y^2\le n\text{; }y\gets y+1\text{)}\\ 3&\qquad\textbf{if }\gcd(x,y)=1\text{ and }(x-y)\bmod2=1\\ 4&\qquad\quad a=2xy\text{, }b=x^2-y^2\text{, }c=x^2+y^2\\ 5&\qquad\quad\textbf{if }a>b\\ 6&\qquad\qquad\text{swap }a,b\\ 7&\qquad\quad\textbf{for}\text{ (}k\gets1\text{; }kc\le n\text{; }k\gets k+1\text{)}\\ 8&\qquad\qquad\text{add }(ka,kb,kc)\text{ to the answer sequence}\\ 9&\text{sort the answer sequence and print it out} \end{array}

共 1 条回复

09J25105

猪写题解。