zoukankan      html  css  js  c++  java
  • 同构数查找程序的优化过程 Anthony

    //问题说明
    //用c写程序找出2~999之间的同构数,同构数是这样的。他出现在他的平方的右边如5的平方=25,25的右端是5,所以5是一个同构数

    //发现贴上来的原因是我发现这个程序的优化效果比较明显.
    //从最初版到最终版的用时相差100多倍.

    //我使用了多媒体时钟编译时需链接winmm.lib
    //我的编译选项是:
    //cl /O2 /MD /DWIN32 /D_WINDOWS winmm.lib tonggou.cpp

    /////////////////////////////////////////////////////////////////////////////
    //1.最直接的版本(看看我理解错了没有)
    //那么从2开始到31为至的数m,依次求出它们的平方M.
    //将m和M转化为字符串.长度分别是n,mn.
    //从M的第mn-n位开始与m进行字符串的比较.如果相等,m就是同构数.
    /////////////////////////////////////////////////////////////////////////////
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <time.h>
    #include <windows.h>

    int check(int n)
    {
        char buf_n[12] = {0};
        char buf_m[12] = {0};

        itoa(n, buf_n, 10);
        itoa(n * n, buf_m, 10);

        int len_n = strlen(buf_n);
        int len_m = strlen(buf_m);

        if (len_m < len_n)
        {
            return false;
        }

        return 0 == strcmp(buf_n, &buf_m[len_m - len_n]);
    }

    int main()
    {
        DWORD begin = timeGetTime();

        for (int i = 2; i < 100000 ; i++)
        {
            if (check(i))
            {
                printf("%d 是同构,它的平方是%d/n", i, i * i);
            }
        }
        DWORD end = timeGetTime();
        printf("共用时 %d ms", end - begin);
        return 0;
    }


    ////////////////////////////////////////////////////////////////////////////////
    //2.优化版
    ////////////////////////////////////////////////////////////////////////////////
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <time.h>
    #include <windows.h>

    int top(int n)
    {
        int top_n = 10;
        while (n > top_n - 1)
        {
            top_n *= 10;
        }
        return top_n;
    }

    int check(int n)
    {
        return (n * n - n) % top(n) == 0;
    }

    int main()
    {
        DWORD begin = timeGetTime();

        for (int i = 2; i < 100000 ; i++)
        {
            if (check(i))
            {
                printf("%d 是同构,它的平方是%d/n", i, i * i);
            }
        }
        DWORD end = timeGetTime();
        printf("共用时 %d ms", end - begin);
        return 0;
    }


    ////////////////////////////////////////////////////////////////////////////////
    //3.最终版
    //分析:
    //n * n = x*100 + n
    //n * n - n - x = 0;
    //解得
    // n = 1/2 + sqrt(4*x + 1)/2
    // x = 10 * y或100*y 或1000*y (y 为自然数) 取值与 n的大小有关
    // 只有1, 9结尾的数才有形为xxx1的平方数.
    // k = sqrt(4 * x + 1) = 2 * n - 1 <= 999 * 2 - 1 = 1997
    //
    // 解决方案
    //    在2~1997范围内,取1或9结尾的数, k
    //   由 n = (k + 1) /2 求取n
    //    由 x = (k * k - 1) /4 求取x
    //    判断 n 和 x的关系是否满足要求: x % top(n) == 0
    //
    ////////////////////////////////////////////////////////////////////////////////
    #include <stdio.h>
    #include <time.h>
    #include <windows.h>

    int top(int n)
    {
        int top_n = 10;
        while (n > top_n - 1)
        {
            top_n *= 10;
        }
        return top_n;
    }

    int getn(int k)
    {
        return (k + 1) / 2;
    }

    int getx(int k)
    {
        int sqrt_4x = k* k - 1;

        if (sqrt_4x & 0x3)
        {
            //不能整除4
            return 0;
        }

        return sqrt_4x >> 2;
    }

    bool check(int k)
    {
        int n = getn(k);
        int x = getx(k);

        if (x > 0 && n > 1)
        {
            return x % top(n) == 0;
        }
        return false;
    }

    int max_k(int n)
    {
        return n * 2;
    }

    #define N 100000

    int main()
    {
        DWORD begin = timeGetTime();

        int array_k[100];
        int count_k = 0;

        for (int i = 11; i < max_k(100000) ; i += 10)
        {
            if (check(i))
            {
                array_k[count_k++] = i;
            }
        }

        for (int i = 9; i < max_k(100000) ; i += 10)
        {
            if (check(i))
            {
                array_k[count_k++] = i;
            }
        }

        for (int i = 0; i < count_k; i++)
        {
            int n = getn(array_k[i]);
            printf("%d 是同构,它的平方是%d/n", n, n * n);
        }

        DWORD end = timeGetTime();
        printf("共用时 %d ms", end - begin);
        return 0;
    }
    /*
    前两版都有溢出的bug,最终版没有.

    执行结果(PIII 500MHz)
    1.直观版
    ---------- Run Application ----------
    5 是同构,它的平方是25
    6 是同构,它的平方是36
    25 是同构,它的平方是625
    76 是同构,它的平方是5776
    376 是同构,它的平方是141376
    625 是同构,它的平方是390625
    9376 是同构,它的平方是87909376
    87231 是同构,它的平方是-980687231
    共用时 183 ms

    优化版
    ---------- Run Application ----------
    5 是同构,它的平方是25
    6 是同构,它的平方是36
    25 是同构,它的平方是625
    76 是同构,它的平方是5776
    376 是同构,它的平方是141376
    625 是同构,它的平方是390625
    9376 是同构,它的平方是87909376
    87232 是同构,它的平方是-980512768
    共用时 9 ms

    3.最终版
    ---------- Run Application ----------
    6 是同构,它的平方是36
    76 是同构,它的平方是5776
    376 是同构,它的平方是141376
    9376 是同构,它的平方是87909376
    5 是同构,它的平方是25
    25 是同构,它的平方是625
    625 是同构,它的平方是390625
    共用时 3 ms

    其实想起来,做到优化版就可以了.必竟写程序也要时间,我在直观版用了10分钟,优化版用了5分种,而终版用了一个小时(主要是分析过程).
    总体来说,做到最终版不合算.
    */

  • 相关阅读:
    HierarchicalDataTemplate
    Prism技巧
    常用Exception
    netcore URL重新路径
    Nintendo Switch相册整理
    交换变量-不借助任何变量
    QCombobox样式stylesheet总结
    Qt新旧Moc方式升级功能
    QSS使用方法总结
    【QRegExp】QLineEdit屏蔽空格
  • 原文地址:https://www.cnblogs.com/ahuangliang/p/5309292.html
Copyright © 2011-2022 走看看