• 勾股数组及其应用uva106


    勾股数组

    设三元组(a,b,c)满足a^2 + b^2 = c^2的勾股数组,那么是否存在无穷多个勾股数组呢,

    答案是肯定的,将三元组乘以d,可以得到新的三元组(da,db,dc) 即(da)^2 + (db)^2 = (dc)^2 --> (a^2+b^2) * d^2 =c^2 * d^2

    d的取值是任意的,所以存在多个勾股数组

    本源勾股数组

    本源勾股数组是一个三元组(a,b,c),其中a,b,c只存在公因数1,且满足a^2 + b^2 = c^2

    积累数据:下面的一些本源勾股数组

     (3,4,5), (5,12,13) ,(8,15,17),(7,24,25)

     (20,21,29),(9,40,41),(12,35,37),(11,60,61)

    分析数据:

    由这些数据可以推断出可能存在一个结论,即a,b的奇偶性不同,且c总是奇数

    证明:如果a,b都是偶数,那么c肯定也是偶数,那么a,b,c存在公因子2,所以三元组不是本源的

      如果a,b都是奇数, 那么c必然是偶数。 设a=2*x+1, b=2*y+1,c=2*z将其带入a^2 + b^2 = c^2

      得到(2x+1)^2 + (2y+1)^2 = (2z)^2 --> 4x^2+4x+4y^2+4y+2=4z^2 -->  2x^2+2x+2y^2+2y+1=2z^2

      式子的左边是一个奇数,而右边是偶数,所以上述假设不成立

      所以a,b一个是偶数,一个是奇数,从而c是奇数

      

    怎么快速得到一定范围内的本源勾股数组

    (a,b,c)是本源勾股数组, 且a是奇数 ,b是偶数,c是奇数,那么可以进行因式分解,

    a^2 = c^2 - b^2 = (c-b)(c+b)

    3^2 = (5-4)(5+4) = 1 * 9

    15^2 = (17-8)(17+8) = 9 * 25

    32^2 = (37-12)(37+12) = 25 * 49

    好像c-b与c+b总是平方数,

    证明:假设(c-b)%d==0 && (c+b)%d==0, 那么根据模的性质,有(c+b)+(c-b) = 2c, 2c%d==0, 且(c+b)-(c-b)=2b,2b%d==0,

      即d整除2b和2c, 因为b和c没有公因数,所以d只能是1或者2, 由(c+b)(c-b)=a^2 也是d的倍数,且a是奇数,所以a^2是奇数,所以d只能取值1

      所以(c-b)与(c+b)互素,且(c-b)(c+b)=a^2, 即(c-b)与(c+b)的和是平方数,这种情况只有在(c-b)与(c+b)本身都是平方数的时候才出现

    如图:

      

    因为(c-b)与(c+b)互素,所以pi 与qi肯定是不相同的,但是(c-b)(c+b)=a^2, 所以指数ai ,bi肯定是偶数的,所以(c+b) 和 (c-b)本身都是平方数

      设c+b=s^2,c-b=t^2, 其中s>t>=1是没有公因数的奇数

      解方程得 

    uva106 

    给我们一定n,要我们求1->n内有多少个本源勾股数组, 和多少个不属于勾股数组的数字

     1 #include <stdio.h>
     2 #include <string.h>
     3 #include <stdlib.h>
     4 #include <algorithm>
     5 #include <iostream>
     6 #include <queue>
     7 #include <stack>
     8 #include <vector>
     9 #include <map>
    10 #include <set>
    11 #include <string>
    12 #include <math.h>
    13 using namespace std;
    14 #pragma warning(disable:4996)
    15 typedef long long LL;                   
    16 const int INF = 1<<30;
    17 /*
    18 
    19 */
    20 bool vis[1000000 + 10];
    21 int ans1[1000000 + 10];
    22 int gcd(int a, int b)
    23 {
    24     if (b == 0)
    25         return a;
    26     return gcd(b, a%b);
    27 }
    28 int main()
    29 {
    30     int s, t, a, b, c;
    31     int cnt = 0, n;
    32     while (scanf("%d", &n) != EOF)
    33     {
    34         cnt = 0;
    35         memset(ans1, 0, sizeof(ans1));
    36         memset(vis, 0, sizeof(vis));
    37         int m = sqrt(2*n);
    38         for (s = 3; s <= m; s += 2)
    39         {
    40             for (t = 1; t < s; t += 2)
    41             {
    42                 if (gcd(s, t) != 1) continue;
    43                 a = s * t;
    44                 b = (s*s - t*t) / 2;
    45                 c = (s*s + t*t) / 2;
    46                 if (c>n) break;
    47                 if ((LL)a*a + (LL)b*b == (LL)c*c)
    48                 {
    49                     //printf("%d %d %d
    ", a, b, c);
    50                     ans1[c]++;
    51                     for (int i = a, j = b, k = c; k <= n; i += a, j += b, k += c)
    52                         vis[i] = vis[j] = vis[k] = true;
    53                 }
    54                 else if ((LL)a*a + (LL)b*b < (LL)c*c)
    55                     break;
    56             }
    57         }
    58 
    59         for (int i = 1; i <= n; ++i)
    60         {
    61             ans1[i] += ans1[i - 1];
    62             if (!vis[i])
    63                 cnt++;
    64         }
    65         printf("%d %d
    ", ans1[n], cnt);
    66     }
    67     return 0;
    68 }
    View Code
  • 相关阅读:
    bzoj 3732: Network 树上两点边权最值
    思维题题集--------一直都很害怕这些题
    Regionals 2014 >> Asia
    小小粉丝度度熊 二分答案 + two pointer
    I
    Binary Strings Gym
    卸载虚拟机时错误关闭了某个服务,使得电脑除了chrome浏览器都不能联网
    双系统给ubuntu增加分区
    tomcat问题
    eclipse:报错信息The superclass “javax.servlet.http.HttpServlet” was not found on the Java Build Path
  • 原文地址:https://www.cnblogs.com/justPassBy/p/4490561.html
Copyright © 2020-2023  润新知