bzoj 1041: [HAOI2008]圆上的整点 (数学)

题目描述

传送门

题目大意:求一个给定的圆(x^2+y^2=r^2),在圆周上有多少个点的坐标是整数。

题解

x2+y2=r2
x2=r2y2
x=(r+y)(ry)
d=gcd(r+y,ry),A=r+yd,B=ryd
式子变形为 x2=d2AB
因为x,d都是完全平方数,所以 AB 也是完全平方数, A!=B 所以 A,B 分别是完全平方数。
那么设 A=aa,B=bb
a2=r+yd,b2=ryd
a2+b2=2rd
那么枚举2r的因数d,再枚举a,判断是否有满足条件的(a,b),更新答案即可。

代码

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<cstring>
#define LL long long 
using namespace std;
LL r,ans;
LL gcd(LL x,LL y)
{
    if (!x||!y) return 0;
    LL r;
    while (y){
        r=x%y;
        x=y; y=r;
    }
    return x;
}
bool check(LL x,LL y)
{
    if (x!=y&&gcd(x,y)==1) return true;
    return false;
}
void solve(LL x)
{
    LL t=2*r/x;
    for (LL i=1;i<=sqrt(t/2.0);i++) {
        LL a=floor((double)sqrt((t-i*i)*1.0));
        if ((a*a+i*i)!=t) continue;
        if(check(a,i)) ans++;
    }
}
int main()
{
    freopen("a.in","r",stdin);
    scanf("%lld",&r);
    for (LL d=1;d*d<=2*r;d++)
     if ((2*r)%d==0) {
        solve(d);
        if (d*d!=r*2) solve(2*r/d);
     }
    printf("%lld\n",ans*4+4);
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值