Input A positive integer n . Output All ordered positive integer triples ( a , b , c ) , that satisfy 1 ≤ a ≤ b ≤ c ≤ n and a 2 + b 2 = c 2 , 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}
Input Output A positive integer n . All ordered positive integer triples ( a , b , c ) , that satisfy 1 ≤ a ≤ b ≤ c ≤ n and a 2 + b 2 = c 2 , sorted in ascending order with a as the first key and b as the second key.
算法 1
枚举 a , b , c a,b,c a , b , c 并判断即可。
时间复杂度为 O ( n 3 ) O(n^3) O ( n 3 ) ,能通过 easy version。
1 for a ← 1 to n 2 for b ← a to n 3 for c ← b to n 4 if a 2 + b 2 = c 2 5 print ( 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}
1 2 3 4 5 for a ← 1 to n for b ← a to n for c ← b to n if a 2 + b 2 = c 2 print ( a , b , c )
算法 2
枚举 a , b a,b a , b ,判断 a 2 + b 2 \sqrt{a^2+b^2} a 2 + b 2 是否为 ≤ n \le n ≤ n 的整数。
这可以变通成判断 c = ⌊ a 2 + b 2 ⌋ c=\lfloor\sqrt{a^2+b^2}\rfloor c = ⌊ a 2 + b 2 ⌋ 是否满足 c ≤ n c\le n c ≤ n 且 a 2 + b 2 = c 2 a^2+b^2=c^2 a 2 + b 2 = c 2 。
时间复杂度为 O ( n 2 ) O(n^2) O ( n 2 ) ,能通过 medium version。
1 for a ← 1 to n 2 for b ← a to n 3 c ← ⌊ a 2 + b 2 ⌋ 4 if c ≤ n and a 2 + b 2 = c 2 5 print ( 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}
1 2 3 4 5 for a ← 1 to n for b ← a to n c ← ⌊ a 2 + b 2 ⌋ if c ≤ n and a 2 + b 2 = c 2 print ( a , b , c )
算法 3
笔者原初的想法是这样的:
把 a 2 + b 2 = c 2 a^2+b^2=c^2 a 2 + b 2 = c 2 变形成 a 2 = ( c + b ) ( c − b ) a^2=(c+b)(c-b) a 2 = ( c + b ) ( c − b ) 。
枚举 a a a ,根据 a a a 的质因数分解枚举 a 2 a^2 a 2 的约数 d d d ,解 { c − b = d c + b = a 2 d \begin{cases}c-b=d\\c+b=\dfrac{a^2}{d}\end{cases} ⎩ ⎨ ⎧ c − b = d c + b = d a 2 并判断是否满足 a ≤ b ≤ c ≤ n a\le b\le c\le n a ≤ b ≤ c ≤ n 。
求 1 , 2 , ⋯ , n 1,2,\cdots,n 1 , 2 , ⋯ , n 的质因数分解可用欧拉筛预处理,对于每个 a a a 还需把 a 2 a^2 a 2 的约数排序。
时间复杂度为 O ( ∑ i = 1 n d ( i 2 ) log d ( i 2 ) ) = O ( n log 2 n log log n ) 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)} O ( i = 1 ∑ n d ( i 2 ) log d ( i 2 ) ) = O ( n l o g 2 n l o g l o g n ) ,能通过 hard version。
procedure EulerSieve 1 for i ← 2 to n 2 if i hasn’t been marked as a composite number 3 smallestPrimeFactor [ i ] ← i 4 add i to the prime sequence 5 for each prime j that satisfies j ≤ smallestPrimeFactor [ i ] and i j ≤ n 6 smallestPrimeFactor [ i j ] ← j 7 mark i j as a composite number function getFactors ( a ′ , d ) 1 if a ′ = 1 2 add d to the factor sequence 3 return 4 v ← smallestPrimeFactor [ a ′ ] , cnt ← 0 5 while v ∣ a ′ do 6 a ′ ← a ′ v , cnt ← cnt + 1 7 for i ← 0 to 2 cnt 8 getFactors ( a ′ , d ) 9 d ← d v procedure mainSolve 1 run EulerSieve 2 for a ← 1 to n 3 clear the factor sequence, run getFactors ( a , 1 ) 4 sort the factor sequence in descending order 5 for each d in the sorted factor sequence that satisfies d < a 6 b ← 1 2 ( a 2 d − d ) , c ← 1 2 ( a 2 d + d ) 7 if a ≤ b and c ≤ n 8 print ( 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}
procedure EulerSieve 1 2 3 4 5 6 7 for i ← 2 to n if i hasn’t been marked as a composite number smallestPrimeFactor [ i ] ← i add i to the prime sequence for each prime j that satisfies j ≤ smallestPrimeFactor [ i ] and ij ≤ n smallestPrimeFactor [ ij ] ← j mark ij as a composite number function getFactors ( a ′ , d ) 1 2 3 4 5 6 7 8 9 if a ′ = 1 add d to the factor sequence return v ← smallestPrimeFactor [ a ′ ] , cnt ← 0 while v ∣ a ′ do a ′ ← v a ′ , cnt ← cnt + 1 for i ← 0 to 2 cnt getFactors ( a ′ , d ) d ← d v procedure mainSolve 1 2 3 4 5 6 7 8 run EulerSieve for a ← 1 to n clear the factor sequence, run getFactors ( a , 1 ) sort the factor sequence in descending order for each d in the sorted factor sequence that satisfies d < a b ← 2 1 ( d a 2 − d ) , c ← 2 1 ( d a 2 + d ) if a ≤ b and c ≤ n print ( a , b , c )
算法 4
大多数同学都通过查阅资料或询问 AI 得到以下做法。
对于 ( a , b , c ) (a,b,c) ( a , b , c ) ,记 d = gcd ( a , b ) d=\gcd(a,b) d = g cd( a , b ) ,若 d > 1 d>1 d > 1 ,称它由 ( a d , b d , c d ) \left(\dfrac{a}{d},\dfrac{b}{d},\dfrac{c}{d}\right) ( d a , d b , d c ) 生成,例如 ( 6 , 8 , 10 ) (6,8,10) ( 6 , 8 , 10 ) 由 ( 3 , 4 , 5 ) (3,4,5) ( 3 , 4 , 5 ) 生成。称满足 d = 1 d=1 d = 1 的 ( a , b , c ) (a,b,c) ( a , b , c ) 为本原勾股三元组,考虑枚举它,生成 ( k a , k b , k c ) (ka,kb,kc) ( ka , kb , k c ) (k c ≤ n kc\le n k c ≤ n )。
下面考察本原勾股三元组 ( a , b , c ) (a,b,c) ( a , b , c ) 的性质:
首先,a , b a,b a , b 一奇一偶。a , b a,b a , b 不可能均为偶数,而若 a , b a,b a , b 均为奇数,则 c 2 c^2 c 2 是 2 2 2 的倍数但非 4 4 4 的倍数,与 c 2 c^2 c 2 是平方数矛盾。因此,可暂且忽略 a , b a,b a , b 之间的大小关系,设 a a a 是偶数,b b b 是奇数,显然 c c c 是奇数。
考察 a 2 = ( c + b ) ( c − b ) a^2=(c+b)(c-b) a 2 = ( c + b ) ( c − b ) ,有 c + b 2 , c − b 2 \dfrac{c+b}{2},\dfrac{c-b}{2} 2 c + b , 2 c − b 是互质的平方数:若不互质,设 gcd ( c + b , c − b ) = 2 d > 2 \gcd(c+b,c-b)=2d>2 g cd( c + b , c − b ) = 2 d > 2 ,则 2 d ∣ 2 b 2d\mid2b 2 d ∣ 2 b ,从而 d ∣ b d\mid b d ∣ b ,d ∣ c d\mid c d ∣ c ,d ∣ a d\mid a d ∣ a ,矛盾!c + b 2 , c − b 2 \dfrac{c+b}{2},\dfrac{c-b}{2} 2 c + b , 2 c − b 互质且乘积是平方数 a 2 4 \dfrac{a^2}{4} 4 a 2 ,根据质因数分解这两个数是互质的平方数。
设 c + b = 2 x 2 c+b=2x^2 c + b = 2 x 2 ,c − b = 2 y 2 c-b=2y^2 c − b = 2 y 2 ,满足 gcd ( x , y ) = 1 \gcd(x,y)=1 g cd( x , y ) = 1 ,解得
{ a = 2 x y b = x 2 − y 2 c = x 2 + y 2 \begin{cases}
a=2xy\\
b=x^2-y^2\\
c=x^2+y^2
\end{cases}
⎩ ⎨ ⎧ a = 2 x y b = x 2 − y 2 c = x 2 + y 2
另一方面,考虑枚举 1 ≤ y < x 1\le y<x 1 ≤ y < x 满足 gcd ( x , y ) = 1 \gcd(x,y)=1 g cd( x , y ) = 1 且 x 2 + y 2 ≤ n x^2+y^2\le n x 2 + y 2 ≤ n ,得到 a , b , c a,b,c a , b , c 。此外,x , y x,y x , y 的奇偶性要不同,否则 b , c b,c b , c 是偶数。目前确有 a 2 + b 2 = c 2 a^2+b^2=c^2 a 2 + b 2 = c 2 ,还需证明 gcd ( a , b ) = 1 \gcd(a,b)=1 g cd( a , b ) = 1 :若不然,设 gcd ( a , b ) = d > 1 \gcd(a,b)=d>1 g cd( a , b ) = d > 1 ,则 d ∣ b = x 2 − y 2 , c = x 2 + y 2 d\mid b=x^2-y^2,c=x^2+y^2 d ∣ b = x 2 − y 2 , c = x 2 + y 2 ,d d d 是奇数且 d ∣ 2 y 2 d\mid2y^2 d ∣ 2 y 2 ,从而 d ∣ y 2 d\mid y^2 d ∣ y 2 ,d ∣ x 2 d\mid x^2 d ∣ x 2 ,与 x 2 , y 2 x^2,y^2 x 2 , y 2 、x , y x,y x , y 互质矛盾!
综上,我们得以精确地找出勾股数,只不过还需排序。根据算法 3 的思路和参考文章 ,勾股三元组个数的量级不高于 O ( n log 2 n ) O(n\log^2n) O ( n log 2 n ) 。若直接一起排序,时间复杂度为 O ( n log 3 n ) O(n\log^3n) O ( n log 3 n ) ,能通过 hard version。
1 for ( x ← 2 ; x 2 < n ; x ← x + 1 ) 2 for ( y ← 1 ; y < x and x 2 + y 2 ≤ n ; y ← y + 1 ) 3 if gcd ( x , y ) = 1 and ( x − y ) m o d 2 = 1 4 a = 2 x y , b = x 2 − y 2 , c = x 2 + y 2 5 if a > b 6 swap a , b 7 for ( k ← 1 ; k c ≤ n ; k ← k + 1 ) 8 add ( k a , k b , k c ) to the answer sequence 9 sort 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 2 3 4 5 6 7 8 9 for ( x ← 2 ; x 2 < n ; x ← x + 1 ) for ( y ← 1 ; y < x and x 2 + y 2 ≤ n ; y ← y + 1 ) if g cd( x , y ) = 1 and ( x − y ) mod 2 = 1 a = 2 x y , b = x 2 − y 2 , c = x 2 + y 2 if a > b swap a , b for ( k ← 1 ; k c ≤ n ; k ← k + 1 ) add ( ka , kb , k c ) to the answer sequence sort the answer sequence and print it out
共 1 条回复
猪写题解。