首页 > 代码库 > BZOJ 1041 HAOI2008 圆上的整点 数论
BZOJ 1041 HAOI2008 圆上的整点 数论
题目大意:给定一个半径为为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; }
BZOJ 1041 HAOI2008 圆上的整点 数论
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。