| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 831 人关注过本帖
标题:求10w以内的所有整数的勾股组合 有木有快一点的方法
只看楼主 加入收藏
神机军师
Rank: 7Rank: 7Rank: 7
来 自:游鱼潜水
等 级:黑侠
威 望:2
帖 子:202
专家分:542
注 册:2013-12-21
结帖率:88.89%
收藏
已结贴  问题点数:20 回复次数:11 
求10w以内的所有整数的勾股组合 有木有快一点的方法
程序代码:
#include<stdio.h>
#include<math.h>
int main(void)
{
    double a;
    double b;
    double c;

    for (a = 1; a <= 100000; a++)
    {
        for (b = a; b <= 100000; b++)
        {
            c = sqrt(a * a + b * b);
            if (c <= 100000)
            {
                if ( c == (int)c)
                {
                    printf("a=%d,b=%d,c=%d\n", (int)a, (int)b, (int)c);
                }
            }
        }
    }

    return (0);
}


死慢死慢的 我就是都给查了一遍, 有没有快一点的算法?
另外 呃 有没有什么方法能跳过那个判断是不是整数的那部分(就是通过整型来写出来程序)
2014-02-28 22:59
beyondyf
Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19
等 级:贵宾
威 望:103
帖 子:3282
专家分:12654
注 册:2008-1-21
收藏
得分:10 
数论中对勾股数有专门的探讨(一般在不定方程的章节),建议看一下。即使看不懂证明过程,也可以把结论记下来。

10W以内的勾股数共有161436组。送你一段代码,也许你还能从中学到一种有趣的语法,呵呵,但要慎用。对于C++,可以用内联函数代替之。

程序代码:
#include <stdio.h>

#define gcd(a, b) ({int r, n, m; for(n = (a), m = (b); r = n % m; n = m, m = r); m;})

void Pythagorean(int range)
{
    int a, b, aa, bb, x, y, z, tx, ty, tz, i = 0;
    for(a = 1; (aa = a * a) < range; a++)
    for(b = 1 + (a & 1); b < a && (bb = b * b) + aa <= range; b += 2)
    if(gcd(a, b) == 1)
    {
        tx = x = 2 * a * b;
        ty = y = aa - bb;
        tz = z = aa + bb;
        for(; tz <= range; tx += x, ty += y, tz += z)
            printf("[%d] : %d %d %d\n", ++i, tx, ty, tz);
    }
}

int main()
{
    Pythagorean(100000);
    return 0;
}

重剑无锋,大巧不工
2014-03-01 01:15
azzbcc
Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19
来 自:江西财经大学
等 级:贵宾
威 望:81
帖 子:3293
专家分:12919
注 册:2012-11-4
收藏
得分:10 
程序代码:
/**

 * (c + b)(c - b) = a * a

 * 令 a * a = x * y,解得:

 * b = (y - x) / 2, c = (y + x) / 2
**/

#include <math.h>
#include <stdio.h>
#include <limits.h>

#define MAX 30000

struct MyStruct
{
    int N;
    struct Struct
    {
        int n, count;
    }data[6];
}sa;

int count = 4, prime[9592] = {2, 3, 5, 7};

/*

 * 初始化质数表
**/
void Init()
{
    int n, i, flag;

    for (n = 10;n < MAX;n += 1)
    {
        flag = 1;
        for (i = 0;prime[i] * prime[i] <= n;i++)
        {
            if (0 == n % prime[i])
            {
                flag = 0;
                break;
            }
        }
        if (flag)
        {
            prime[count++] = n;
        }
    }
}

/*

 * 将 n 分解质因数,存入结构体 sa
**/
void InitSA(int n)
{
    int i = 0;

    sa.N = 0;
    while (1 != n)
    {
        while (0 != n % prime[i]) i += 1;

        sa.data[sa.N].n     = prime[i];
        sa.data[sa.N].count = 0;
        while (0 == n % prime[i])
        {
            n /= prime[i];
            sa.data[sa.N].count += 1;
        }
        sa.N += 1;
    }
}

/*

 * a * a = x * y
**/
void Show1(int step, int x, int n)
{
    int i, y, b, c;

    if (step == sa.N)
    {
        y = n * n / x;
        b = (y - x) / 2;
        c = (y + x) / 2;
        if (c <= MAX && b > n)
        {
            printf_s("%6d, %6d, %6d\n", n, b, c);
        }
        return;
    }

    for (i = 0;i <= sa.data[step].count * 2;i += 1)
    {
        if (i) x *= sa.data[step].n;
        if (x >= n) { return;}
        Show1(step + 1, x, n);
    }
}

/*

 * a * a = 2 ^ p = (2 ^ n) * (2 ^ (p - n))
**/
void Show2(int p, int n)
{
    int i, x = 1, y, b, c;

    for (i = 1;i < p;i += 1)
    {
        x *= 2;
        y = n * n / x;
        b = (y - x) / 2;
        c = (y + x) / 2;
        if (c <= MAX && b > n)
        {
            printf_s("%6d, %6d, %6d\n", n, b, c);
        }
    }
}

/*

 * a * a = 2 ^ p * M = (2 ^ n * x) * (2 ^ (p - n) * y)
**/
void Show3(int step, int x, int n, int p, int N)
{
    int i, y, b, c;

    if (step == sa.N)
    {
        if (x * x != n) p *= 2;
        for (i = 1;i < p;i += 1)
        {
            x *= 2;
            y = N * N / x;
            b = abs(y - x) / 2;
            c = (y + x) / 2;
            if (c <= MAX && b > N)
            {
                printf_s("%6d, %6d, %6d\n", N, b, c);
            }
        }
        return;
    }

    for (i = 0;i <= sa.data[step].count;i += 1)
    {
        if (i) x *= sa.data[step].n;
        if (x * x > n) { return;}
        Show3(step + 1, x, n, p, N);
    }
}

int main(int argc, char* argv[])
{
    int   a, p, M;
    FILE* fp;

    Init();
    freopen_s(&fp, "out.txt", "w", stdout);
    for (a = 3;a <= MAX;a += 1)
    {
        if (0 != a % 2)
        {
            InitSA(a);
            Show1(0, 1, a);
            continue;
        }

        M = a, p = 0;
        while (0 == M % 2)
        {
            p += 1;
            M /= 2;
        }

        if (1 == M)
        {
            Show2(p, a);
        }
        else
        {
            InitSA(M);
            Show3(0, 1, M, p, a);
        }
    }
    fclose(stdout);

    return 0;
}


[fly]存在即是合理[/fly]
2014-03-01 02:09
beyondyf
Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19
等 级:贵宾
威 望:103
帖 子:3282
专家分:12654
注 册:2008-1-21
收藏
得分:0 
回复 3楼 azzbcc
测试了一下你的代码。在输出100以内的勾股数时少了8组,具体是
18 24 30
24 45 51
30 40 50
36 48 60
40 75 85
42 56 70
54 72 90
60 80 100
再完善一下你的算法。

重剑无锋,大巧不工
2014-03-02 09:39
azzbcc
Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19
来 自:江西财经大学
等 级:贵宾
威 望:81
帖 子:3293
专家分:12919
注 册:2012-11-4
收藏
得分:0 
忽略了 1 * 2 ^ p 的情况,修改版
程序代码:
/*
* a * a = 2 ^ p = (2 ^ n) * (2 ^ (p - n))
**/
void Show2(int p, int n)
{
    int i, x = 1, y, b, c;

    for (i = 0;i <= p;i += 1)
    {
        if (i)    x *= 2;
        y = n * n / x;
        b = (y - x) / 2;
        c = (y + x) / 2;
        if (c <= MAX && b > n)
        {
            printf_s("%6d, %6d, %6d\n", n, b, c);
        }
    }
}

/*
* a * a = 2 ^ p * M = (2 ^ n * x) * (2 ^ (p - n) * y)
**/
void Show3(int step, int x, int n, int p, int N)
{
    int i, y, b, c;

    if (step == sa.N)
    {
        if (x * x != n) p *= 2;
        for (i = 0;i <= p;i += 1)
        {
            if (i)    x *= 2;
            y = N * N / x;
            b = abs(y - x) / 2;
            c = (y + x) / 2;
            if (c <= MAX && b > N)
            {
                printf_s("%6d, %6d, %6d\n", N, b, c);
            }
        }
        return;
    }

    for (i = 0;i <= sa.data[step].count;i += 1)
    {
        if (i) x *= sa.data[step].n;
        if (x * x > n) { return;}
        Show3(step + 1, x, n, p, N);
    }
}


[fly]存在即是合理[/fly]
2014-03-02 13:56
beyondyf
Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19
等 级:贵宾
威 望:103
帖 子:3282
专家分:12654
注 册:2008-1-21
收藏
得分:0 
回复 5楼 azzbcc
还是测试的100以内的数据,结果还是不对。呵呵,再检查一下你的代码吧

具体为

16组错误数据
     4,      7,      8
     6,     17,     18
     8,     31,     32
    10,     49,     50
    12,     71,     72
    14,     97,     98
    14,     22,     26
    18,     38,     42
    18,     52,     55
    22,     58,     62
    24,     27,     36
    26,     82,     86
    30,     31,     43
    42,     67,     79
    44,     52,     68
    52,     76,     92

缺少6组正确数据
24 45 51
30 40 50
40 75 85
42 56 70
54 72 90
60 80 100

这里将100以内的所有勾股数发上来供测试参考
[1] 3 4 5
[2] 5 12 13
[3] 6 8 10
[4] 7 24 25
[5] 8 15 17
[6] 9 12 15
[7] 9 40 41
[8] 10 24 26
[9] 11 60 61
[10] 12 16 20
[11] 12 35 37
[12] 13 84 85
[13] 14 48 50
[14] 15 20 25
[15] 15 36 39
[16] 16 30 34
[17] 16 63 65
[18] 18 24 30
[19] 18 80 82
[20] 20 21 29
[21] 20 48 52
[22] 21 28 35
[23] 21 72 75
[24] 24 32 40
[25] 24 45 51
[26] 24 70 74
[27] 25 60 65
[28] 27 36 45
[29] 28 45 53
[30] 28 96 100
[31] 30 40 50
[32] 30 72 78
[33] 32 60 68
[34] 33 44 55
[35] 33 56 65
[36] 35 84 91
[37] 36 48 60
[38] 36 77 85
[39] 39 52 65
[40] 39 80 89
[41] 40 42 58
[42] 40 75 85
[43] 42 56 70
[44] 45 60 75
[45] 48 55 73
[46] 48 64 80
[47] 51 68 85
[48] 54 72 90
[49] 57 76 95
[50] 60 63 87
[51] 60 80 100
[52] 65 72 97

重剑无锋,大巧不工
2014-03-02 16:30
azzbcc
Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19
来 自:江西财经大学
等 级:贵宾
威 望:81
帖 子:3293
专家分:12919
注 册:2012-11-4
收藏
得分:0 
哎,不够严谨啊。

程序代码:
/**

 * (c + b)(c - b) = a * a

 * 令 a * a = x * y,解得:

 * b = (y - x) / 2, c = (y + x) / 2
**/

#define _CRT_SECURE_NO_WARNINGS

#include <math.h>
#include <stdio.h>

#define MAX 100

struct MyStruct
{
    int N;
    struct Struct
    {
        int n, count;
    }data[6];
}sa;

int count = 4, prime[9592] = {2, 3, 5, 7};

/*

 * 初始化质数表
**/
void Init()
{
    int n, i, flag;

    for (n = 10;n < MAX;n += 1)
    {
        flag = 1;
        for (i = 0;prime[i] * prime[i] <= n;i++)
        {
            if (0 == n % prime[i])
            {
                flag = 0;
                break;
            }
        }
        if (flag)
        {
            prime[count++] = n;
        }
    }
}

/*

 * 将 n 分解质因数,存入结构体 sa
**/
void InitSA(int n)
{
    int i = 0;

    sa.N = 0;
    while (1 != n)
    {
        while (0 != n % prime[i]) i += 1;

        sa.data[sa.N].n     = prime[i];
        sa.data[sa.N].count = 0;
        while (0 == n % prime[i])
        {
            n /= prime[i];
            sa.data[sa.N].count += 1;
        }
        sa.N += 1;
    }
}

/*

 * a * a = x * y
**/
void Show1(int step, int x, int a)
{
    int i, y, b, c;

    if (step == sa.N)
    {
        y = a * a / x;
        b = (y - x) / 2;
        c = (y + x) / 2;
        if (c <= MAX && b > a)
        {
            printf("%6d, %6d, %6d\n", a, b, c);
        }
        return;
    }

    for (i = 0;i <= sa.data[step].count * 2;i += 1)
    {
        if (i) x *= sa.data[step].n;
        if (x >= a) { return;}
        Show1(step + 1, x, a);
    }
}

/*

 * a * a = 2 ^ p = (2 ^ n) * (2 ^ (p - n))
**/
void Show2(int p, int a)
{
    int i, x = 1, y, b, c;

    for (i = 1;i < p;i += 1)
    {
        x *= 2;
        y  = a * a / x;

        b = (y - x) / 2;
        c = (y + x) / 2;
        if (c <= MAX && b > a)
        {
            printf("%6d, %6d, %6d\n", a, b, c);
        }
    }
}

/*

 * a * a = 2 ^ p * M = (2 ^ n * m) * (2 ^ (p - n) * m)
**/
void Show3(int a, int p, int m)
{
    int i, b, c, y, x = m;

    for (i = 1;i < p;i += 1)
    {
        x *= 2;
        y  = a * a / x;

        b = (y - x) / 2;
        c = (y + x) / 2;
        if (c <= MAX && b > a)
        {
            printf("%6d, %6d, %6d\n", a, b, c);
        }
    }
}

/*

 * a * a = 2 ^ p * M = (2 ^ n * x) * (2 ^ (p - n) * y) (x != y)
**/
void Show4(int step, int x, int n, int p, int a)
{
    int i, b, c, y;

    if (step == sa.N)
    {
        for (i = 1;i < p * 2;i += 1)
        {
            x *= 2;
            y  = a * a / x;

            b = abs(y - x) / 2;
            c = (y + x) / 2;
            if (c <= MAX && b > a)
            {
                printf("%6d, %6d, %6d\n", a, b, c);
            }
        }
        return;
    }

    for (i = 0;i <= sa.data[step].count * 2;i += 1)
    {
        if (i) x *= sa.data[step].n;
        if (x >= n) { return; }
        Show4(step + 1, x, n, p, a);
    }
}

int main(int argc, char* argv[])
{
    int   a, p, M;

    Init();
    freopen("out.txt", "w", stdout);
    for (a = 3;a <= MAX;a += 1)
    {
        if (0 != a % 2)
        {
            InitSA(a);
            Show1(0, 1, a);
            continue;
        }

        M = a, p = 0;
        while (0 == M % 2)
        {
            p += 1;
            M /= 2;
        }

        if (1 == M)
        {
            Show2(p, a);
        }
        else
        {
            InitSA(M);
            Show3(a, p, M);
            Show4(0, 1, M, p, a);
        }
    }
    fclose(stdout);

    return 0;
}


[fly]存在即是合理[/fly]
2014-03-02 23:02
神机军师
Rank: 7Rank: 7Rank: 7
来 自:游鱼潜水
等 级:黑侠
威 望:2
帖 子:202
专家分:542
注 册:2013-12-21
收藏
得分:0 
回复 2楼 beyondyf
谢版主

未知令人期待!
2014-03-03 16:32
神机军师
Rank: 7Rank: 7Rank: 7
来 自:游鱼潜水
等 级:黑侠
威 望:2
帖 子:202
专家分:542
注 册:2013-12-21
收藏
得分:0 
回复 3楼 azzbcc
谢版主!! 程序我会仔细看的

未知令人期待!
2014-03-03 16:33
beyondyf
Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19
等 级:贵宾
威 望:103
帖 子:3282
专家分:12654
注 册:2008-1-21
收藏
得分:0 
回复 7楼 azzbcc
虽然这并不影响我对你代码的看法,但看到标准函数比看到微软的受控函数确实舒服多了呵呵。

下一步该解决一下计算的范围了。你当前的代码只能计算到46340以内,还达不到10W。使用64位整型是一个办法,但还可以更高效一些(基于你的算法)。

重剑无锋,大巧不工
2014-03-03 16:34
快速回复:求10w以内的所有整数的勾股组合 有木有快一点的方法
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.024095 second(s), 7 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved