bzoj 1041 数论

7 篇文章 0 订阅
1 篇文章 0 订阅

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

这居然不是几何题(╯‵□′)╯︵┻━┻

这居然是道数轮题(╯-_-)╯╧╧  

我们只考虑x>0 且 y>0 即在第一象限的情况,然后最终=第一象限答案*4 + 4(坐标轴上的四个点)

x^2+y^2=r^2

即 y^2 = r^2-x^2 = (r+x)(r-x)

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

所以 r+x=d*U ,r-x=d*V 且 gcd(U,V)=1

所以 y^2 = d^2 +U*V

因为y^2 和 d^2 都是完全平方数

又因为x>0 即 U<>V

所以U和V也都是完全平方数

令U=u*u,V=v*v (u>v>0 且 gcd(u,v)=1)

则有 2*r=(r+x) + (r-x) = d*(u*u+v*v) ; x=[(r+x)-(r-x)] / 2 = d(u*u-v*v)/2 ; y = d*u*v

所以我们枚举2*r的因数d,再枚举u,并计算出 v=sqrt(2*r/d - u*u) ,然后判断u和v是否满足条件 (用U和V判断也可以)

即 u>v>0 且 gcd(u,v)=1 且 u*u+v*v=2*r/d (U和V必须是完全平方数)

var
        r,ans,d,u,v     :int64;
        i               :longint;
function gcd(a,b:int64):int64;
begin
   if b=0 then exit(a) else exit(gcd(b,a mod b));
end;

procedure work(t:int64);
var
        j:longint;
begin
   for j:=1 to trunc(sqrt(t)) do
   begin
      u:=int64(j);
      v:=trunc(sqrt(t-u*u));
      if u>v then
      begin
         if (gcd(u,v)=1) and (u*u+v*v=t) and (v<>0) then inc(ans);
      end;
   end;
end;

begin
   read(r);
   r:=r<<1; ans:=1;
   for i:=1 to trunc(sqrt(r)) do
   begin
      d:=int64(i);
      if (r mod d=0) then
      begin
         work(r div d);
         if d*d<>r then work(d);
      end;
   end;
   ans:=ans<<2;
   writeln(ans);
end.
——by Eirlys



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值