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

来源:互联网 发布:zram内存优化 编辑:程序博客网 时间:2024/06/05 15:03

传送门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 longusing 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
原创粉丝点击