CF1487-D. Pythagorean Triples

题意

给出一个n让找出符合一下要求的勾股数\((a,b,c)\)的数量:

  1. \(0<a\le b \le c \le n\)
  2. \(c=a^2-b\).

思路

\(\begin{cases}c^2=a^2+b^2\\c=a^2-b\end{cases}\Rightarrow\begin{cases}c^2=a^2+b^2\\c^2=a^4-2a^2b+b^2\end{cases}\Rightarrow a^2+b^2=a^4-2a^2b+b^2\Rightarrow a^2=1+2b\Rightarrow c=1+b\).

容易证明当\(b\geq3\)的时候\(a^2\leq b^2\)始终成立,且\(c=b+1\),所以当\(b\geq 3\)的时候有\(a<=b<=c\)恒成立,因此\(b=\frac{a^2-1}{2}\geq 3\Rightarrow a\geq \sqrt{7}>2\).

每个\(a\)都能唯一确定一个\(b\)\(c\),那么只要计算出符合要求的\(a\)有多少个就是最终的答案。

这里\(c=b+1=\frac{a^2+1}{2}\)要小于等于\(n\)\(c=\frac{a^2+1}{2}<=n\Rightarrow a\leq \sqrt{2n-1}\).

因为\(a^2=1+2b\)\(b>0,b\subseteq Z\),所以\(a^2\)为奇数,所以\(a\)也是奇数。

综上所述可以取到的\(a\)的数量为\(n_a=\frac{\sqrt{2n-1}-1}{2}\).

AC代码

#include <cstdio>
#include <cmath>

typedef long long ll;

void solve() {
    ll n;
    scanf("%lld", &n);
    printf("%lld\n", ((ll)std::sqrt(2 * n - 1) - 1) / 2);
}

int main() {
    int T;
    scanf("%d", &T);
    while (T--) {
        solve();
    }
    return 0;
}
posted @ 2021-03-09 22:39  牟翔宇  阅读(59)  评论(0编辑  收藏  举报