题意:求a*a + b*b = c*c (a < b < c <= n && a,b,c互质)的解的个数,[1,n]中不出现在a*a + b*b = c*c (a < b < c <= n)中的数的个数
需要的知识点:本原勾股数组,本原勾股数组(PPT)是一个三元组(a,b,c),其中a,b,c无公因数,且满足a² + b² =c²。其它的勾股数组为(i*a)^2 + (i*b)^2 = (i*c)^2,
思路分析:首先说明下这题数据非常水,即使用暴力也能过。但是暴力做没啥意义。这题的关键在求本原勾股数组
需要的知识点:本原勾股数组,本原勾股数组(PPT)是一个三元组(a,b,c),其中a,b,c无公因数,且满足a² + b² =c²。其它的勾股数组为(i*a)^2 + (i*b)^2 = (i*c)^2,
思路分析:首先说明下这题数据非常水,即使用暴力也能过。但是暴力做没啥意义。这题的关键在求本原勾股数组
s,t为奇数(s > t >= 1),并且gcd(s,t) == 1,那么a = st; b = (s*s-t*t); c = (s*s+t*t)/2;如果你想知道为什么,请参考http://www.cnblogs.com/PegasusWang/archive/2013/01/22/2872213.html
代码如下:
#include<iostream>
#include<algorithm>
#include<cstring>
#include<string>
#include<stack>
#include<queue>
#include<set>
#include<map>
#include<stdio.h>
#include<stdlib.h>
#include<math.h>
#define LL __int64
#define N 1000005
#define inf 0x7ffffff
#define eps 1e-9
#define pi acos(-1.0)
using namespace std
int vis[N];
int gcd(LL a,LL b)
{
return a%b == 0 ? b : gcd(b,a%b);
}
int main()
{
//freopen("input.txt","r",stdin);
//freopen("output.txt","w",stdout);
int n;
while(scanf("%d",&n) != EOF)
{
memset(vis,0,sizeof(vis));
LL s,t;
int flag = 1,ans = 0;
for(s = 3; s <= n; s += 2)
{
for(t = 1; t < s; t += 2)
if(gcd(s,t) == 1)
{
LL a = s*t;
LL b = (s*s-t*t)/2;
LL c = (s*s+t*t)/2;
if(c <= n)
{
ans++;
for(int i = 1; ; i++){
if(c*i > n) break;
vis[i*a] = vis[i*b] = vis[i*c] = 1;
}
}
// printf("%I64d %I64d %I64d\n",a,b,c);
}
}
int ans1 = 0;
for(int i = 1; i <= n; i++)
if(vis[i] == 0)
ans1++;
printf("%d %d\n",ans,ans1);
}
return 0;
}