【bzoj1041】圆上的整点
题意
给定一个圆\(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】圆上的整点的更多相关文章
- bzoj1041 圆上的整点 数学
题目传送门 题目大意:求一个给定的圆(x^2+y^2=r^2),在圆周上有多少个点的坐标是整数. 思路:没思路,看大佬的博客(转载自https://blog.csdn.net/csyzcyj),转载只 ...
- [BZOJ1041]圆上的整点
嗯... 自己看视频讲解? >Click Here< #include<cstdio> #include<queue> #include<iostream&g ...
- 【BZOJ1041】[HAOI2008]圆上的整点
[BZOJ1041][HAOI2008]圆上的整点 题面 bzoj 洛谷 题解 不妨设\(x>0,y>0\) \[ x^2+y^2=r^2\\ y^2=(x+r)(x-r) \] 设\(r ...
- 【BZOJ1041】圆上的整点(数论)
[BZOJ1041]圆上的整点(数论) 题面 BZOJ 洛谷 题解 好神仙的题目啊. 安利一个视频,大概是第\(7\)到\(19\)分钟的样子 因为要质因数分解,所以复习了一下\(Pollard\_r ...
- 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 ...
- BZOJ1041 [HAOI2008]圆上的整点 【数学】
1041: [HAOI2008]圆上的整点 Time Limit: 10 Sec Memory Limit: 162 MB Submit: 4631 Solved: 2087 [Submit][S ...
- BZOJ 1041: [HAOI2008]圆上的整点
1041: [HAOI2008]圆上的整点 Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 3621 Solved: 1605[Submit][Sta ...
- bzoj 1041: [HAOI2008]圆上的整点 数学
1041: [HAOI2008]圆上的整点 Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://www.lydsy.com/JudgeOnline/ ...
- bzoj 1041: [HAOI2008]圆上的整点 本原勾股數組
1041: [HAOI2008]圆上的整点 Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 2027 Solved: 853[Submit][Stat ...
- 1041: [HAOI2008]圆上的整点
1041: [HAOI2008]圆上的整点 Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 4298 Solved: 1944[Submit][Sta ...
随机推荐
- 查看linux发行版本、内核版本命令
查看linux发行版本: $lsb_release -a 查看linux内核版本: $cat /proc/version 或 $uname -a
- VS为VC++添加UAC控制(VC程序默认管理员运行)
1.VS编译链接VC++工程生成文件默认是没有管理员权限的 生成的程序图标是没有盾牌的如图: 如果程序需要在C盘做些写入操作 就必须具有管理员权限 所以需要在工程中进行设置. 注:自己项目的安装程序安 ...
- C#闪屏
using System;using System.Collections.Generic;using System.ComponentModel;using System.Data;using Sy ...
- BZOJ 3241: [Noi2013]书法家
题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=3241 题意: 思路:把每个字母分成三部分,两个字母之间还有空的列,所以我一共设了11个状态 ...
- Python串口编程
python的串口网上有很多例子,这里了只是把认为好的整理到一起. 首先,应该安装serial模块,还能开始后续的操作.我用的python2.6,serial模块可以在这里下载安装serial模块下载 ...
- DbUtils使用时抛出Cannot get a connection
java.sql.SQLException: Cannot get a connection, pool error Timeout waiting for idle object Caused by ...
- How To PLAY_SOUND in Oracle Forms
Play_sound is used to play audio files in Oracle Forms, Play_Sound plays the sound object in the spe ...
- 生产者-消费者 用非阻塞队列、Object.wait()、Object.notify()实现
非阻塞队列,需要考虑到: 1.并发中的同步 2.线程间通信 public class Quene_Pro_Con { //定义队列大小 private static int size = 10; // ...
- hnoi 2016 省选总结
感觉省选好难的说...反正我数据结构太垃圾正解想到了也打不出来打一打暴力就滚粗了! DAY1 0+20+30 DAY2 60-20+0+60 最后170-20分,暴力分还是没有拿全! 然而这次是给了5 ...
- Fiddler界面详解
Statistics 页签 完整页签如下图: Statistics 页签显示当前用户选择的 Sessions 的汇总信息,包括:选择的 Sessions 总数.发送字节数.接收字节数.响应类型的汇总表 ...