Uva 106 - Fermat vs. Pythagoras 解题报告

 

 

 

 

        数论题,考查了本原勾股数(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 }
View Code

 

    

posted @ 2013-12-01 18:59  keambar  阅读(307)  评论(0编辑  收藏  举报