BZOJ 1041 HAOI2008 圆上的整点 数论

42 篇文章 0 订阅

题目大意:给定一个半径为为r的圆x^2+y^2=r^2,求圆上多少个点的坐标为整数

卡了很久的一道题。。。我之前用了两个公式,理论上可以O(√n)出解,可惜这两个公式并不能涵盖所有勾股数。。。

于是去找了下题解,发现这样一种方法:(原帖地址: http://www.cppblog.com/zxb/archive/2010/10/18/130330.html )

x^2+y^2=r^2

化简为 y^2=(r-x)(r+x)

我们令d=gcd(r-x,r+x)

则(r-x)/d与(r+x)/d一定互质,二者相乘为完全平方数,则二者一定都为完全平方数

令r-x=d*u^2,r+x=d*v^2

则有u,v互质,u<v

其中x=d(v^2-u^2)/2

        y=d*u*v

        r=d*(u^2+v^2)/2

枚举2r的因数d,对于每个d我们用O[√(r/d)]的时间枚举u 代入r的计算式得出v^2 计算v^2是否为完全平方数及u与v是否互质

这样可以枚举出一个象限内的整点个数 然后输出(ans+1)*4即可

#include<cmath>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
typedef long long ll;
ll r,ans;
ll factors[100100];
int tot;
void Get_Factors(ll x)
{
	ll i;
	for(i=1;i*i<x;i++)
		if(x%i==0)
			factors[++tot]=i,factors[++tot]=x/i;
	if(i*i==x)
		factors[++tot]=i;
}
ll GCD(ll x,ll y)
{
	return y?GCD(y,x%y):x;
}
bool Is_Square(ll x)
{
	double temp=sqrt( (double)x );
	if(fabs(floor(temp+1e-7)-temp)<1e-7)\
		return true;
	return false;
}
int main()
{
	cin>>r;
	int i;
	ll u;
	Get_Factors(r<<1);
	for(i=1;i<=tot;i++)
	{
		ll d=factors[i];
		for(u=1;u*u<(r+1)/d;u++)
		{
			ll v_2=r*2/factors[i]-u*u;
			if( Is_Square(v_2) )
				if(GCD(v_2,u*u)==1)
					++ans;
		}
	}
	cout<<(ans+1<<2)<<endl;
}



  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 5
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值