【codevs1867】【Tyvj3508】【BZOJ1041】圆上的整点,数学乱搞

传送门1
传送门2
传送门3
写在前面:乱搞数学……
思路:
原博文

这里写图片描述
有了上面的推理,那么实现的方法为:

枚举d∈[1,sqrt(2R)],然后根据上述推理可知:必先判d是否为2R的一约数。

此时d为2R的约数有两种情况:d=d或d=2R/d。

第一种情况:d=2R/d。枚举a∈[1,sqrt(2R/2d)] <由2*a*a <
2*R/d转变来>,算出对应的b=sqrt(2R/d-a^2),检查是否此时的A,B满足:A≠B且A,B互质
<根据上面的推理可知必需满足此条件>,若是就将答案加1

第二种情况:d=d。枚举a∈[1,sqrt(d/2)] <由2*a*a <
d转变来>,算出对应的b=sqrt(d-a^2),检查是否此时的A,B满足:A≠B且A,B互质
<根据上面的推理可知必需满足此条件>,若是就将答案加1

因为这样只算出了第一象限的情况<上面枚举时均是从1开始枚举>,根据圆的对称性,其他象限的整点数与第一象限中的整点数相同,最后,在象限轴上的4个整点未算,加上即可,那么最后答案为ans=4*第一象限整点数+4

感觉一做数学题就成煞笔了呢……
注意:LL
代码:

#include<bits/stdc++.h>
#define LL long long
using namespace std;
LL k,r,ans,p,d;
LL gcd(LL x,LL y)
{
    if (y==0) return x;
    return gcd(y,x%y);
}
main()
{
    scanf("%lld",&r);
    k=r<<1; 
    for (int i=1;i<=sqrt(k);i++)
    if (k%i==0)
    {
        d=i;
        for (int j=1;j<=sqrt(r/d);j++)
        {
            p=sqrt(k/d-j*j);
            if (p*p+j*j==k/d&&gcd(p*p,j*j)==1&&p!=j) ans++;
        }
        d=k/i;
        for (int j=1;j<=sqrt(r/d);j++)
        {
            p=sqrt(k/d-j*j);
            if (p*p+j*j==k/d&&gcd(p*p,j*j)==1&&p!=j) ans++;
        }
    }
    printf("%lld",4*ans+4);
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值