UVA106- Fermat vs. Pythagoras(素勾股數)
阿新 • • 發佈:2019-01-30
題意:給你一個n,讓你找出一些勾股陣列,a^2+b^2=c^2 , 需要滿足a<b<c<=n 。 對於每個case題目首先需要你輸出這些勾股陣列中素勾股數T的個數,然後再輸出一個數字,這個數字是n-所有勾股陣列用掉的數字個數
思路:本題就是要求在n範圍內的素勾股數,在維基百科內找到相關的資料
如果 (a, b, c) 是勾股數,它們的正整數倍數,也是勾股數,即 (na, nb, nc) 也是勾股數。若果 a, b, c 三者互質(它們的最大公因數是 1),它們就稱為素勾股數。
以下的方法可用來找出勾股數。設 m > n 、 m 和 n 均是正整數,
a = m * m - n * n;
b = 2 * m * n;
c = m * m + n * n;
#include <iostream> #include <cstdio> #include <cstring> #include <cmath> const int N = 1000005; long long n; int vis[N]; long long gcd(long long a, long long b) { return b == 0 ? a : gcd(b, a % b); } int main() { while (scanf("%lld", &n) != EOF) { int ans1 = 0, ans2 = 0; memset(vis, 0, sizeof(vis)); long long m = sqrt(n + 0.5); long long a, b, c; for (long long i = 1; i <= m; i++) { for (long long j = i + 1; j <= m; j += 2) { if (gcd(j, i) == 1) { a = j * j - i * i; b = 2 * i * j; c = i * i + j * j; if (c <= n) { ans1++; vis[a] = vis[b] = vis[c] = 1; } for (int k = 2; c * k <= n; k++) vis [k * a] = vis[k * b] = vis[k * c] = 1; } } } for (int i = 1; i <= n; i++) if (vis[i]) ans2++; printf("%d %d\n", ans1++, n - ans2++); } return 0; }