[BZOJ1041][HAOI2008][數學亂搞]圓上的整點

[Problem Description]
求一個給定的圓(x^2+y^2=r^2),在圓周上有多少個點的座標是整數。
[Algorithm]
數學亂搞
[Analysis]
題目倒是很簡潔明瞭……但是有點讓人無從下手
我們一步一步來分析:
首先寫出式子 X ^ 2 + Y ^ 2 = R ^ 2
移項 Y ^ 2 = R ^ 2 - X ^ 2
          = (R + X)(R - X)
設 d = GCD(R + X, R - X)
則 Y ^ 2 = d ^ 2 * (R + X) / d * (R - X) / d
設 A = (R + X) / d, B = (R - X) / d
 A != B 且 GCD(A, B) = 1
 Y ^ 2 = d ^ 2 * A * B
由於Y ^ 2 是完全平方數, d ^ 2也是完全平方數, 而A, B互質,所以A, B都是完全平方數
設 A = a ^ 2, B = b ^ 2
則 a ^ 2 + b ^ 2 = 2 * R / d
說明 d 是 2 * R 的因數,以此可以在[1, sqrt(2 * R)]的範圍內枚舉i,當2 * R % i == 0時,i 和 2 * R / i都是2 * R 的因數。確定 2 * R / d 的值,假設a < b,我們再在[1, sqrt((2 * R / d) / 2)]的範圍內枚舉a, 算出對應的 A, b, B, 如果A, B都是完全平方數而且 A != B, GCD(A, B) == 1則方案數加1。這是一個象限的方案數,最後再* 4 再加上座標軸上的4個即可
[Pay Attention]
用long long啊用long long!
注意以後求勾股數相關的都可以利用這裏推出的結論……
[Code]
/**************************************************************
    Problem: 1041
    User: gaotianyu1350
    Language: C++
    Result: Accepted
    Time:80 ms
    Memory:1284 kb
****************************************************************/
 
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <cstring>
#include <iostream>
using namespace std;
 
const long long INF = 2000000000;
long long ans = 0;
long long r;
 
long long gcd(long long a, long long b)
{
    return !b ? a : gcd(b, a % b);
}
 
void solve(long long left)
{
    long long temp = (int) sqrt(left / 2);
    for (long long a = 1; a <= temp; a++)
    {
        long long A = a * a;
        long long B = left - A;
        long long b = (int)sqrt(B);
        if (b * b == B && gcd(A, B) == 1 && A != B)
            ans++;
    }
}
 
int main()
{
    scanf("%lld", &r);
    long long tar = (int)sqrt(2 * r);
    for (long long i = 1; i <= tar; i++)
        if (2 * r % i == 0)
        {
            solve(2 * r / i);
            solve(i);
        }
    printf("%lld\n", ans * 4 + 4);
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章