题意

给定一个圆\(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. Android Handler Message总结

    http://blog.csdn.net/caesardadi/article/details/8473777 当应用程序启动时,会开启一个主线程(也就是UI线程),由她来管理UI,监听用户点击,来响 ...

  2. 一、java环境搭建

    结论: 1.jdk包括jre,jre包括jvm. 2.eclipse ide依赖环境变量.如果未设置,在启动eclipse工具会提示:返回码是13.

  3. 批量修改文件夹及文件用户权限和用户组权限 centos

    chown -R www *   批量修改目录下所有文件,用户为www chown -R :www *  批量修改目录下所有文件,用户组为www

  4. Cheatsheet: 2013 10.24 ~ 10.31

    Web Performance Comparison Between Node.js and Java EE Other Hidden Productivity Secrets With Alfred ...

  5. 【转载】COM的多线程模型

    原文:COM的多线程模型 COM的多线程模型是COM技术里头最难以理解的部分之一,很多书都有涉及但是都没有很好的讲清楚.很多新人都会在这里觉得很迷惑,google大神能搜到一篇vckbase上的文章, ...

  6. ps aux 查看进程信息

    [root@localhost Desktop]# ps auxUSER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMANDroot 1 0.0 0.3 ...

  7. Creating HTML table with vertically oriented text as table header 表头文字方向

    AS an old question, this is more like info or reminder about vertical margin or padding in % that ta ...

  8. [HDOJ5763]Another Meaning(KMP, DP)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5763 题意:给定两个字符串a和b,其中a中的字符串如果含有子串b,那么那部分可以被替换成*.问有多少种 ...

  9. Spring的IoC容器注入的类型

    Spring除了可以注入Bean实例外,还可以注入其他数据类型. 注入基本数据类型 xml配置文件中的init-method="init"属性是取得Bean实例之后,输入属性值后自 ...

  10. Java中正则表达式的使用

    public class Test{ public static void main(String args[]) { String str="@Shang Hai Hong Qiao Fe ...