SDUT 1149 勾股定理第一弹 勾股数

http://acm.sdut.edu.cn/sdutoj/showproblem.php?pid=1493&cid=1149

题意:中文......

思路:

首先对于基本勾股数来说,有这样一个特点即gcd(a,b,c) = 1; 而对于所有勾股数有gcd(a,b) = gcd(b,c) = gcd(a,c);

存在一个构造基本勾股数的方法:

条件 :(m > n > 0) ,gcd(m,n) = 1 , m 与 n 的奇偶性不同  => a = m*m - n*n ; b = 2*n*m; c = m*m + n*n;   a.b,c不确定到底谁最大。

根据题意我们知道,a + b + c = s; => m*(m + n)*d = s;(d表示基本勾股数的多少倍,来求出所有的勾股数)。 令 k = (m + n), k一定是奇数。

我们首先枚举m  m < ceil(sqrt(s) - 1  , 得到m后,由于   k < 2*m(n < m) ,k < (m + n)*d里面最大的奇数。然后再枚举k,  m,k都知道了,那么结果也就知道了,

我们取C最大的哪个就可以了。

#include <iostream>  

#include <cstdio>  

#include <cstring>  

#include <algorithm>  

#include <cmath>  

#include <queue>  

#include <stack>  

#include <set>  

#include <map>  

#include <string>  

  

#define CL(a,num) memset((a),(num),sizeof(a))  

#define iabs(x)  ((x) > 0 ? (x) : -(x))  

  

#define maxn 50004  

#define ll long long  

#define inf 0x7f7f7f7f  

#define MOD 100000007  

#define lc l,m,rt<<1  

#define rc m + 1,r,rt<<1|1  

using namespace std;  

  

int gcd(int x,int y)  

{  

    if (x < y) swap(x,y);  

    if (y == 0) return x;  

    return gcd(y,x%y);  

}  

int main()  

{  

//    freopen("din.txt","r",stdin);  

//    freopen("dou.txt","w",stdout);  

    int a,b,c,d;  

    int s,k;  

    int m,n,t;  

    ll ans;  

    while (~scanf("%d",&s))  

    {  

        if (!s) break;  

        t = 0; ans = 0;  

        int top = ceil(sqrt(s/2.0)) - 1;  

        for (m = 2; m <= top; ++m)  //枚举m 

        {  

            if (s % m == 0)  //m是s的因子

            {  

                //sm存(m + n)*d的最大奇因子

                int sm = s/m;  

                while (sm % 2 == 0) sm /= 2;  

                if (m&1) k = m + 2;  

                else k = m + 1;  

                //枚举k

                for (; k < 2*m && k <= sm; k += 2)  

                {  

  

                    if (sm%k == 0 && gcd(k - m,m) == 1 && ((m^(k - m))&1) == 1)  

                    {  

  

                        d = s / (k * m * 2);  

//                        printf("%d %d %d %d\n",m,k - m,k,sm);  

                        n = k - m;  

                        if (n > m) swap(n,m);  

                        a = d*(m*m - n*n);  

                        b = 2*d*(m*n);  

                        c = d*(m*m + n*n);  

//                        printf("%d %d %d %lld\n",a,b,c,(ll)a*b*c);  

                        if (a > 0 && b > 0 && c > 0 && a + b + c == s && max(a,max(b,c)) > t)  

                        {  

                            ans = (ll)a*b*c;  

                            t = c;  

                        }  

                    }  

                }  

            }  

        }  

        cout<<ans<<endl;  

    }  

}  

  

 

 

 

你可能感兴趣的:(du)