题解 BZOJ1041/luogu P2508 [HAOI2008]圆上的整点

3 篇文章 0 订阅
1 篇文章 0 订阅

Description

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

Input

只有一个正整数n,n<=2000 000 000

Output

整点个数

Sample Input

4

Sample Output

4

解法:

一道极其经典的题……
还有一个极其经典的题解。
不过先说两句我的想法:由于数据范围比较大,所以显然不能直接从1到r枚举x之类。于是我们就需要想到一个更好的枚举坐标的办法。
这样我们就想到了一个奇怪的推导 使得我们缩小了需要枚举的范围。
具体的过程看这个博客就好啦!
http://blog.csdn.net/csyzcyj/article/details/10044629
不过几个需要注意的地方:他说的d有两种情况,因为他两个情况用的同一个d,我搞混了之后弄了很久才明白。可以自己把第一个d代换成d‘。
两个数互质的话,它们的平方肯定也互质。
然后还有判断一个数是否是完全平方数的神奇方法:
double x=sqrt(n);
floor(x)==x的话n就是完全平方数。

代码

#include<iostream>
#include<cstdio>
#include<cmath>
using namespace std;
typedef long long ll;
ll gcd(ll a,ll b)
{
  if(a<b)swap(a,b);
  return a%b==0?b:gcd(b,a%b);
}
bool check(ll x,double y)
{
  if(floor(y)==y)
  {
    ll y1=(ll)floor(y);
    if(gcd(x,y1)==1 && x!=y1) return true;
  }
  return false;
}
int main()
{
  ll r;
  scanf("%lld",&r);
  ll ans=0;
  for(ll d=1;d*d<=2*r;d++)
  {
    if((2*r)%d==0)
    {
      for(long long a=1;a<=(long long)sqrt(r/d);a++)
      {
        double b=sqrt(((2*r)/d)-a*a);
        if(check(a,b)) ans++;
      }
      if(d!=(2*r)/d)
      {
        for(long long a=1;a<=(long long)sqrt(d/2);a++)
        {
          double b=sqrt(d-a*a);
          if(check(a,b)) ans++;
        }
      }
    }
  }
  printf("%lld",ans*4+4);
  return 0;
}

好啦晚安xD

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值