题意

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

\(r\leq 2*10^9\)

分析

这道题目关键要知道一些勾股数的性质,剩下的就很好处理了。

勾股数的性质

参考勾股数的基本组及其性质

定义1

如果正整数\(a\),\(b\),\(c\)能满足不定方程\(a^2+b^2=c^2\),则它们叫一组勾股数,用\([a,b,c]\)表示。

定义2

如果\([a,b,c]\)为一勾股数组,且\((a,b)=1\),则\([a,b,c]\)叫一个勾股数的基本组;全体勾股数的基本组用集合\(A\)表示。

定义3

若\([a,b,c]\)为一勾股数的基本组,则\([ka,kb,kc]\)叫一勾股数的导出组,其中\(k\in N^+\)

定理1

若\([a,b,c]\in A\),则\((a,b)=(a,c)=(b,c)=(a,b,c)=1\)

定理2

若\([a,b,c]\)为一勾股数组,且\((a,b)=d>1\),则\([a,b,c]\)为一勾股数的导出组。

定理3

若\([a,b,c]\in A\),则\(a\)与\(b\)一奇一偶,\(c\)为奇数。

定理4

一切勾股数的基本组可用下述公式表示:

\(a=2mn,b=m^2-n^2,c=m^2+n^2\),其中\(m,n\)为正整数且\(m>n\),\((m,n)=1\),一奇一偶。

定理5

若\(a^2+b^2=c^2\),\((a,b,c)=(a,b)=(b,c)=(a,c)=1\),则对于\(c-a\)和\(c-b\),一个是完全平方数\(x^2\),一个是完全平方数的两倍\(2y^2\)

思路1:定理5

\(x^2+y^2=r^2\)的整数解的个数,等价于:

①当\(x=0\)或\(y=0\)时,贡献为4;

②当\(x\neq 0\)且\(y\neq 0\)时,由于\((-x)^2=x^2\),所以直接求解正整数解的个数,然后*4即可。

勾股数的组数不多,所以我们要快速求解出所有的勾股数组。

设\(g=\gcd(x,y,r)\),我们枚举所有的\(g\),设\(a={x\over g},b={y\over g},c={r\over g}\),问题转化为求解\(a^2+b^2=c^2\)的基本组\([a,b,c]\)的个数,也就是求\(a^2+b^2=c^2,a>0,b>0,\gcd(a,b)=1\)的解的个数,然后累加答案。

根据定理5,不妨定序,设\(c-a=p^2,c-b=2q^2\),我们枚举所有的\(q\),计算对应的\(a\)和\(b\)。若存在,由于我们进行了定序,所以对答案进行累加为2。

时间复杂度:

\(O(\sqrt r\sum_{d|r}\sqrt d)\)

#include <cstdio>
#include <cmath>

#define rep(i,a,b) for (int i=(a);i<=(b);i++)

typedef long long LL;

int r;
int res;

int gcd(int a,int b)
{
    if (!b) return a;
    else return gcd(b,a%b);
}

int Check(int a,int b,int c)
{
    if (a<1||b<1||c<1) return 0;
    if ((LL)a*a+(LL)b*b!=(LL)c*c) return 0;
    int g=gcd(a,b);
    return g==1;
}

void Solve(int c)
{
    int up=(int)sqrt(c/2);
    rep(q,1,up)
    {
        int b=c-2*q*q;
        int a=(int)sqrt((LL)c*c-(LL)b*b);
        if (Check(a,b,c)) res+=8;
    }
}

int main(void)
{
    #ifndef ONLINE_JUDGE
    freopen("bzoj1041.in","r",stdin);
    freopen("bzoj1041.out","w",stdout);
    #endif

    scanf("%d",&r);

    res+=4;

    int up=(int)sqrt(r);
    rep(g,1,up) if (r%g==0)
    {
        Solve(r/g);                 //g=g
        if (g*g!=r) Solve(g);       //g=r/g
    }

    printf("%d\n",res);

    return 0;
}

思路2:定理4

基本组公式。

根据定理4,

一切勾股数的基本组可用下述公式表示:

\(a=2mn,b=m^2-n^2,c=m^2+n^2\)

和上面一样,只是求\(a^2+b^2=c^2,a>0,b>0,\gcd(a,b)=1\)的解的个数的方法不同。

这里不赘述。

代码更简单,速度也更快。

#include <cstdio>
#include <cmath>

#define rep(i,a,b) for (int i=(a);i<=(b);i++)

int r;
int res;

int gcd(int a,int b)
{
    if (!b) return a;
    else return gcd(b,a%b);
}

void Solve(int c)
{
    int up=(int)sqrt(c/2);
    rep(n,1,up)
    {
        int m=(int)sqrt(c-n*n);
        if (m<=n||m*m+n*n!=c) continue;
        int a=2*m*n,b=m*m-n*n;
        if (gcd(a,b)==1) res+=8;
    }
}

int main(void)
{
    #ifndef ONLINE_JUDGE
    freopen("bzoj1041.in","r",stdin);
    freopen("bzoj1041.out","w",stdout);
    #endif

    scanf("%d",&r);

    res+=4;

    int up=(int)sqrt(r);
    rep(g,1,up) if (r%g==0)
    {
        Solve(g);
        if (g*g!=r) Solve(r/g);
    }

    printf("%d\n",res);

    return 0;
}

小结

(1)要熟记勾股数的这几个性质。

由于证明太过麻烦,时间也不够,就先不看了。

(2)勾股数的个数不多,求解\(x^2+y^2=z^2\)这种不定方程的方法,就是直接利用勾股数的性质加快枚举,找到所有的。

(3)关于代码调试

OI中的代码调试

把数据攻击的方法融入检查的过程中。

【bzoj1041】圆上的整点的更多相关文章

  1. bzoj1041 圆上的整点 数学

    题目传送门 题目大意:求一个给定的圆(x^2+y^2=r^2),在圆周上有多少个点的坐标是整数. 思路:没思路,看大佬的博客(转载自https://blog.csdn.net/csyzcyj),转载只 ...

  2. [BZOJ1041]圆上的整点

    嗯... 自己看视频讲解? >Click Here< #include<cstdio> #include<queue> #include<iostream&g ...

  3. 【BZOJ1041】[HAOI2008]圆上的整点

    [BZOJ1041][HAOI2008]圆上的整点 题面 bzoj 洛谷 题解 不妨设\(x>0,y>0\) \[ x^2+y^2=r^2\\ y^2=(x+r)(x-r) \] 设\(r ...

  4. 【BZOJ1041】圆上的整点(数论)

    [BZOJ1041]圆上的整点(数论) 题面 BZOJ 洛谷 题解 好神仙的题目啊. 安利一个视频,大概是第\(7\)到\(19\)分钟的样子 因为要质因数分解,所以复习了一下\(Pollard\_r ...

  5. bzoj千题计划127:bzoj1041: [HAOI2008]圆上的整点

    http://www.lydsy.com/JudgeOnline/problem.php?id=1041 设 X>0 ,Y>0 X^2 + Y^2 = R^2 X^2 = R^2-Y^2 ...

  6. BZOJ1041 [HAOI2008]圆上的整点 【数学】

    1041: [HAOI2008]圆上的整点 Time Limit: 10 Sec  Memory Limit: 162 MB Submit: 4631  Solved: 2087 [Submit][S ...

  7. BZOJ 1041: [HAOI2008]圆上的整点

    1041: [HAOI2008]圆上的整点 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 3621  Solved: 1605[Submit][Sta ...

  8. bzoj 1041: [HAOI2008]圆上的整点 数学

    1041: [HAOI2008]圆上的整点 Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://www.lydsy.com/JudgeOnline/ ...

  9. bzoj 1041: [HAOI2008]圆上的整点 本原勾股數組

    1041: [HAOI2008]圆上的整点 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 2027  Solved: 853[Submit][Stat ...

  10. 1041: [HAOI2008]圆上的整点

    1041: [HAOI2008]圆上的整点 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 4298  Solved: 1944[Submit][Sta ...

随机推荐

  1. SSH配置私钥登陆服务器

    前言 本文基于实际Linux管理工作,实例讲解工作中使用ssh证书登录的实际流程,讲解ssh证书登录的配置原理,基于配置原理,解决实际工作中,windows下使用SecureCRT证书登录的各种问题, ...

  2. C语言第4天循环,流程控制。

    C语言第四天 :first-child { margin-top: 0; } blockquote > :last-child { margin-bottom: 0; } img { borde ...

  3. JavaBean基础转载

    JavaWeb:JavaBean基础 JavaBean基础 JavaBean简介: 1.JavaBean是一种可以重复使用的类,可以没有用户界面,主要负责业务数据或者处理事物(数据运算.操作数据库) ...

  4. SqlSever基础 datediff 计算两个时间相差多少年份

    镇场诗:---大梦谁觉,水月中建博客.百千磨难,才知世事无常.---今持佛语,技术无量愿学.愿尽所学,铸一良心博客.------------------------------------------ ...

  5. application/x-www-form-urlencoded

    在Form元素的语法中,EncType表明提交数据的格式 用 Enctype 属性指定将数据回发到服务器时浏览器使用的编码类型. 下边是说明: application/x-www-form-urlen ...

  6. CUBRID学习笔记 31 通过select创建表

    语法 CREATE {TABLE | CLASS} <table_name> [( <column_definition> [,<table_constraint> ...

  7. hdu 1116 Play on Words 欧拉路径+并查集

    Play on Words Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)To ...

  8. hdu 4163 Stock Prices 水

    #include<bits/stdc++.h> using namespace std; #define ll long long #define pi (4*atan(1.0)) #de ...

  9. FLASH CC 2015 CANVAS 实际应用过程中遇到的【粉色】问题(不定期更新)

    1,导入音乐导致发布卡死 一开始以为是不支持,FQ搜索了一些帖子,也有说不能再时间轴加音乐,需要用代码加入,想想不太可能啊,如果真的不能为什么IDE不禁用呢? 而实际问题是: 我使用的其中一条音效有问 ...

  10. iOS - Swift Subscript 下标脚本

    1.Subscript 下标脚本允许你通过在实例后面的方括号中传入一个或者多个的索引值来对实例进行访问和赋值.语法类似于实例方法和计算型属性的混合.与定义实例方法类似,定义下标脚本使用 subscri ...