zoukankan      html  css  js  c++  java
  • for循环次数优化

    1、今天遇到了一道有意思的数学题:

      政府采购一批IT配件,总预算10000元,条件如下:

    •  移动硬盘每个500,普通硬盘每个300,U盘3个100;
    •    所有配件个数加起来100个,并且钱刚好花完;

          问题来了: 移动硬盘、普通硬盘、U盘分别买多少个?

     

      这里原理并不复杂,用a、b、c分别表示3种设备的数量,得到如下等式:

     a+b+c=100;

        a*500+b*300+c*100/3 = 10000; 

        

    2、根据上述的限制条件,普通的开发人员不动脑立刻就能想到for循环的解决办法如下:

      

       这么做的时间复杂度是0(N^3);这里还好每次循环只有100次,所以3次循环一共只有10^6次。如果每次循环1000次了,3层嵌套就是10^9=1亿次了,电脑明显会卡顿。如果这样面试大厂,分分钟被面试官教育人生,offer想都不用想了!

    3、第一种优化思路:移动硬盘500元一个,10000元最多买20个;普通硬盘300元一个,10000元最多买33个;U盘100元3个,那么U盘个数肯定是3的倍数,换句话说除以3余数是0,所以新的表达式如下:

      a+b+c=100;

           a*500+b*300+c*100/3 = 10000; 

          其中:    0=<a<=20;  0=<b<=33; c%3=0&c>=0;    根据这种思路的代码如下:

         

       这次结果是对的,但是循环次数已经降到660次,时间复杂度是O(n^2),少了一个数量级;这种代码普通电脑计算时已经毫无压力!

    4、其实还有优化空间,过程推导如下:

    •        a+b+c=100;     ----- 表达式1
    •        a*500+b*300+c*100/3 = 10000;  ----- 表达式2
    •       表达式2两边同时除以100,乘以3得到:15a+9b+c=300;   -----表达式3
    •       由表达式1得到:c=100-a-b, 带入表达式3替换c,最终得到:7a+4b=100  =>  b = 25-7*a/4;-----表达式4
    •       因为b必须是正整数,所以a必须是4的倍数,并且a<=12, 这里记作a=4*i(0=<i<=3);
    •       所以b=25-7*(4*i)/4=25-7*i
    •       又所以c=100-a-b=100-4*i-(25-7*i)=75+3*i

         所以整个代码优化如下:这里只循环4次就搞定了! 本质上是:人为已经把a、b、c的取值计算方式想好,只是通过计算机落实而已!前面两种方式纯粹是通过计算机的算力暴力求解,后面这种是人为优化解法!

        

        循环次数进一步降到4次,时间复杂度降低到O(n);空间复杂度降低到O(1); 

      完整代码如下:

    #include <iostream>
    #include <ctime>
    #include <chrono>
    
    using std::chrono::high_resolution_clock;
    using std::chrono::milliseconds;
    
    int main()
    {
        high_resolution_clock::time_point beginTime1 = high_resolution_clock::now();
        for (int a=0; a<=100;a++)
        {
            for (int b=0;b<=100;b++) 
            {
                for (int c = 0; c <= 100; c++) {
                    if ((a*500+b*300+c*100/3 == 10000)&&(a+b+c==100)) 
                    {
                        printf("移动硬盘:%d; 普通硬盘:%d; U盘:%d
    ",a,b,c);
                    }
                }
            }
        }
        high_resolution_clock::time_point endTime1 = high_resolution_clock::now();
        milliseconds timeInterval1 = std::chrono::duration_cast<milliseconds>(endTime1 - beginTime1);
        std::cout << "运行耗时:"<< timeInterval1.count() << "ms
    ";
        printf("===================================================================>
    ");
    
        high_resolution_clock::time_point beginTime2 = high_resolution_clock::now();
        for (int a = 0; a <= 10000/500; a++)
        {
            for (int b = 0; b <= 10000/300; b++)
            {
                int c = 100 - a - b;
                if (c % 3 != 0) continue;
                if (a * 500 + b * 300 + c * 100 / 3 == 10000)
                {
                    printf("移动硬盘:%d; 普通硬盘:%d; U盘:%d
    ", a, b, c);
                }
             
            }
        }
        high_resolution_clock::time_point endTime2 = high_resolution_clock::now();
        milliseconds timeInterval2 = std::chrono::duration_cast<milliseconds>(endTime2 - beginTime2);
        std::cout << "运行耗时:" << timeInterval2.count() << "ms
    ";
        printf("===================================================================>
    ");
    
        for (int i = 0; i <= 3; i++) 
        {
            printf("移动硬盘:%d; 普通硬盘:%d; U盘:%d
    ", 4*i, 25-7*i, 75+3*i);
        }
    
    
    }
  • 相关阅读:
    jsp、js分页功能的简单总结
    jsp实现验证码
    JSP内置对象总结
    java集合类总结二
    工程一:记事本的实现
    学编程上这些网站就够了
    一位程序员和他的程序员老婆分手了,原因竟是…
    培训机构出来的程序员为何不受企业待见?
    在w3cschool学完html,css,javascript,jquery以后,还是不会做前端怎么办?
    我只是个写代码的(幽默一下)
  • 原文地址:https://www.cnblogs.com/theseventhson/p/14165339.html
Copyright © 2011-2022 走看看