前几天听见他们做了,知道要用新知识,就直接查知识了:来自http://www.leyle.com/archives/361106
毕达哥拉斯三元组——快速生成勾股数
丢番图求毕达哥拉斯三元组的方法
设有任意两个整数,组成如下:
其积的2倍;
两个的平方差;
两者的平方和;
这样就得到了一个勾股数。
如有整数2,3
那么就有
2x3x2=12;
(3×3)-(2×2)=5
(2×2)+(3×3)=13
那么,5,12,13就是勾股数了。
毕达哥拉斯规则还有最后一个调整。计算出三个数后,可以选择我们喜欢的其他任何数来乘以这三个数。
因此,将3-4-5三条边都乘以2可以得到6-8-10这个勾股三角形。
我本来还想不对每次求出的乘以倍数计算,发现是不对的,会漏下很多情况,改后就过了
//============================================================================
// Name : 106.cpp
// Author :
// Version :
// Copyright : Your copyright notice
// Description : Hello World in C++, Ansi-style
//============================================================================
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
using namespace std;
int ans1, ans2, n, a, b, c;
bool flag[1000010];
int gcd(int x, int y){
if(x < y) swap(x, y);
int r;
while(x%y){
r = x%y;
x = y;
y = r;
}
return y;
}
int exprime(int x, int y){
if(gcd(x, y) == 1) return 1;
else return 0;
}
int main(){
freopen("a.txt", "r", stdin);
while(scanf("%d", &n)!=EOF){
memset(flag, false, sizeof(flag));
ans1 = 0;
ans2 = 0;
for(int i = 1;i <= sqrt(n);i++){
for(int j = i+1;j <= sqrt(n);j++){
a = i*j*2;
b = (i*i-j*j)>0?(i*i-j*j):(j*j-i*i);
c = i*i+j*j;
if(a > b) swap(a, b);
if(b > c) swap(b, c);
if(a > b) swap(a, b);
if(a >0&&a <= n&&b > 0&&b <= n&&c > 0&&c <= n){
flag[a] = true;
flag[b] = true;
flag[c] = true;
// printf("%d %d %d\n", a, b, c);
if(exprime(a, b)&&exprime(b, c)&&exprime(a, c)){
ans1++;
for(int k = 2;k*c <= n;k++){
flag[a*k] = true;
flag[b*k] = true;
flag[c*k] = true;
}
}
}
}
}
for(int i = 1;i <= n;i++){
if(flag[i] == false) ans2++;
}
printf("%d %d\n", ans1, ans2);
}
return 0;
}