[BZOJ] 1041 圆上的整点【质因数分解】

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

题解
$x^2+y^2=r^2$
$y=\sqrt{(r+x)*(r-x)}$
$d=gcd((r+x),(r-x))$
$r+x=d*A,r-x=d*B$
$y=\sqrt{d*d*A*B}$
$A=a^2,B=b^2$
$r+x=d*a^2,r-x=d*b^2$
$d*(a^2+b^2)=2*r$
$a^2+b^2=r*2/d$
枚举d,枚举a,检验$gcd(a^2,b^2)$是否等于1,a是否不等于b
还有一个更为精妙的方法:https://www.bilibili.com/video/av12131743/

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cstdio>
#include <cmath> 
using namespace std;
typedef long long LL;
LL r;
int ans=0;

inline bool ok(LL a,LL b)
{
    if(__gcd(a*a,b*b)!=1 || a==b)
        return false;
    return true;
}

int main()
{
    scanf("%lld",&r);
    LL m=sqrt(2*r);
    for(LL d=1;d<=m;d++)
    if((2*r)%d==0)
    {
        LL mm=sqrt(d/2);
        for(LL b=1;b<=mm;b++)
        {
            double tmp=sqrt(d-b*b);
            LL a=(LL)tmp;
            if(a<tmp) continue;
            if(ok(a,b)) ans++;
        }
        if(d!=2*r/d)
        {
            mm=sqrt(r/d);
            for(LL b=1;b<=mm;b++)
            {
                double tmp=sqrt(2*r/d-b*b);
                LL a=(LL)tmp;
                if(a<tmp) continue;
                if(ok(a,b)) ans++;
            }
        }
    }
    printf("%d",ans*4+4);
    return 0;	
}

另一种方法:

#include <iostream>
#include <cmath>
using namespace std;

int main()
{
	int r,ans=1;
	cin>>r;
	int mm=sqrt(r);
	for(int i=2;i<=mm;i++)
	if(r%i==0)
	{
		int p=0;
		while(r%i==0)
		{
			if(i%4!=3)
				p+=2;
			r/=i;
		}
		if(i!=2) ans*=(p+1);
	}
	if(r!=1 && r%4!=3)
		ans*=3;
	cout<<ans*4;
	return 0;
} 

  

posted @ 2018-06-14 09:38  Captain_fcj  阅读(291)  评论(0编辑  收藏  举报