zoukankan      html  css  js  c++  java
  • 数学基础之勾股数

    素勾股数

    勾股数公式的简单推导

    转载自物理学渣的知乎专栏

    勾股数的性质

    (1)定义:凡符合$X^2 + Y^2 = Z^2$公式的正整数我们称之为勾股数。$X$和$Y$代表两条直角边,$Z$代表斜边。

    (2)凡有公约数的勾股数我们称之为派生勾股数,例[30, 40, 50]等;无公约数的勾股数,例[3, 4, 5], [8, 15, 17]等,我们称之为勾股数。全是偶数的勾股数必是派生勾股数,三个奇数不可能符合定义公式。因此,勾股数唯一的可能性是:$X$和$Y$分别是奇数和偶数(偶数和奇数),斜边$Z$则只能是奇数。

    (3)勾股数具有以下特性

    • 斜边与偶数边之差是奇数,这个奇数只能是某奇数的平方数, 例1, 9, 25, 49, ..., 至无穷大;
    • 斜边与奇数边之差是偶数,这个偶数只能是某偶数平方数的一半, 例2, 8, 18, 32, ..., 至无穷大;

    (4)由以上定义我们推导出勾股公式

    $$X = P^2 + PQ$$

    $$Y = Q^2 / 2 + PQ$$

    $$Z = P^2 + Q^2 / 2 + PQ$$

    此公式涵盖了自然界的全部勾股数,包括派生勾股数。

    (5)用此公式很容易导出全部勾股数,例如2000以内的勾股数计有320组(不含派生勾股数)。最大的一组是[315, 1972, 1997]。

    斜边是1105和1885的勾股数各有4组:                     

    • [47, 1104, 1105]  [264, 1703, 1105]  [576, 943, 1105]  [744, 817, 1105];
    • [427, 1836, 1885]  [1003, 1596, 1885]  [1643, 924, 1885]  [1813, 516, 1885];

    (6)以任意奇数代入$P$ ,任意偶数代入$Q$ ,即可得到唯一一组勾股数。

    例如$P = 5, Q = 8$,得到:$X = 25 + 5 × 8 = 65, Y = 32 + 5 × 8 = 72, Z = 25 + 32 + 5 × 8 = 97$。

    它极清楚地显示出了斜边与偶数直角边之差是奇数的平方,斜边与奇数直角边之差是偶数平方值的一半,而斜边则是由奇数的平方与偶数平方的一半和此奇数与偶数之积三项之和所构成。

    (7)当$P$与$Q$有公约数时,例如9与12,再例如21与28等,推导出来的是派生勾股数;当$P$与$Q$无公约数时,例如9与8,再例如21与16等,推导出来的是勾股数;

    (8)不存在不符合本公式的勾股数。例如有人发现趣味勾股数[88209, 90288, 126225],它实际是个派生勾股数,它是[297, 304, 425]乘297倍而成,它是由$P = 11$和$Q = 16$导出。

    (9)本文所提供的公式是依据性质第3条的两条勾股数特性规律推导而出,但是它可以与六百年前印度婆罗门笈多公式相互推导。

    (10)依据本公式勾股定理可从正整数拓展到负整数。在笛卡尔座标图上,勾股三角形可以在更大的位置上显现。

    例题演示

    题目描述

    特殊毕达哥拉斯三元组

    毕达哥拉斯三元组是三个自然数:$a < b < c$组成的集合,并满足$a^2 + b^2 = c^2$。例如,$3^2 + 4^2 = 9 + 16 = 25 = 5^2$。

    有且只有一个毕达哥拉斯三元组满足$a + b + c = 1000$。求这个三元组的乘积$abc$。

    解题思路

    由素勾股数的性质可知,只需要求出素勾股数那么它的倍数也是勾股数,而要求素勾股数要借助性质四。

    代码实现(C)

    #include<stdio.h>
    #include<math.h>
    int gcd(int m, int n) {
        return(n ? gcd(n, m%n) : m); //求最大公约数
    }
    
    int main() {
        int ans = 0;
        for(int n = 1; n <= 33; n++) { 
            for(int m = n + 1; m <= 33; m++) { // m一定要大于n
                if(gcd(m ,n) != 1) continue;
                int a = 2 * n * m;
                int b = m * m - n * n;
                int c = m * m + n * n;
                if(1000 % (a + b + c) == 0) { //如果1000 % (a + b + c) == 0那么要求勾股数就是它的倍数
                    int k = 1000 / (a + b + c);  
                    ans = a * b * c *(int)pow(k, 3);
                }
                
            }
        
        } 
         printf("%d", ans);
    }

    (整理自网络)

    参考资料:

    https://zhuanlan.zhihu.com/p/83522763

    https://www.cnblogs.com/mfryf/archive/2012/02/16/2354116.html

    https://blog.csdn.net/qq_43799957/article/details/99883710

    Min是清明的茗
  • 相关阅读:
    CF1438D Powerful Ksenia(构造题)
    AT5759 ThREE(构造)
    浏览器中上面三个字,下面两个字 两端对齐(转)
    luoguP3372 【模板】线段树 1
    大数据-linux实操篇-组管理和权限管理
    大数据-linux实操篇-解压和压缩类指令
    大数据-linux实操篇-搜索查找类指令
    大数据-linux实操篇-文件目录类指令
    大数据-linux实操篇-帮助指令
    大数据-linux实操篇-实用指令(七个级别、忘记root密码)
  • 原文地址:https://www.cnblogs.com/MinPage/p/14262376.html
Copyright © 2011-2022 走看看