数论题,考查了本原勾股数(PPT)
对一个三元组(a,b,c)两两互质
且满足 a2 + b2 = c2
首先有结论
a 和 b 奇偶性不同 c总是奇数(可用反证法证明,不赘述)
设 a为奇数 b为偶数 a,b,c互质
有
a2 = c2 – b2 =(c-b)(c+b)
由于c和b互质 且a为奇数
(c-b)与(c+b)也互质
令(c+b)=s2 (c-b)=t2
有 c=(s2+t2)/2 b=(s2-t2)/2
a=st
这时可以枚举s 和 t 保证 s t 互质
非本原勾股数只需乘上一个系数即可
1 #include <iostream> 2 #include <math.h> 3 #include <cstring> 4 int flag[1000001]; 5 using namespace std; 6 int main() 7 { 8 int i,m,n,maxm,maxn; 9 int ans=0; 10 for (;cin>>i;ans=0) 11 { 12 memset(flag,0,sizeof flag); 13 maxm=(int)sqrt((float)i-1); 14 for (m=2;m<=maxm;++m) 15 { 16 maxn=(int)sqrt((float)i-m*m); 17 maxn=maxn>=m?m-1:maxn; 18 for(n=1;n<=maxn;++n) 19 { 20 if(n%2!=m%2) 21 { 22 int a=m,b=n,c; 23 for(int r; (r = a % b) != 0; a = b, b = r); 24 if (b == 1) 25 { 26 ++ans; 27 a = m * m - n * n, b = 2 * m * n, c = m * m + n * n; 28 for (int k = 0; c * k <= i; ++k) 29 { 30 flag[a * k] = flag[b * k] = flag[c * k] = 1; 31 } 32 } 33 } 34 } 35 } 36 cout << ans << " "; 37 for (ans = 0, m = 1; m <= i; ans += !flag[m++]); 38 cout << ans << endl; 39 } 40 return 0; 41 }