《趣学算法》-第1章_算法之美

26 篇文章 1 订阅
9 篇文章 0 订阅

马克思手稿中的数学题:一共30人,其中男人,女人,儿童,一家饭店吃饭共花了50先令;每个男人花3先令,每个女人花2先令,每个小孩花费1先令;问男人,女人各多少人?编程实现1-11

#include <iostream>
#include <cstdio>
using namespace std;
int main()
{
    int x,y,z,count = 0;
    cout<<" Men,Women,children "<<endl;
    cout<<"....................."<<endl;
    for(int x=1;x<=9;x++){
        y=20-2*x;
        z=30-x-y;
        if(3*x+2*y+z==50)
        cout<<++count<<" "<<x<<" "<<y<<" "<<z<<endl;
    }

    return 0;
}

以上时间复杂度为O(1)是否还有更优算法?

爱因斯坦的阶梯:

                爱因斯坦家的长阶梯,若每步跨2阶,则最后剩1阶;若每步跨3阶,则最后剩2阶;若每步跨5阶,则最后剩4阶;若每步跨6阶,则最后剩5阶,只有每次跨7阶,最后才正好1阶不剩。求共有多少阶?

            分析:阶梯数n满足:

                        n=1(mod2),n=2(mod3),n=4(mod5),n=5(mod6),n=0(mod7)

只需判断一个整数是否满足上面的5个同余式即可。

#include <bits/stdc++.h>
using namespace std;
int main()
{
    int n=1;
    while(!((n%2==1)&&(n%3==2)&&(n%5==4)&&(n%6==5)&&(n%7==0)))
         n++;
    cout<<"Count the stairs= "<<n<<endl;
    return 0;
}

运行了119次,too confuse,只需将n=1改成n=7,n++改成n=n+7;while语句运行次数就减少了很多。

哥德巴赫猜想:任一大于2的偶数,都可表示成两个素数之和。编程验证2000以内大于2的偶数能够分解为两个素数之和?

首先要先判断分解出的两个整数是否均为素数,若是,满足题意;否则重新进行分解和判断。

素数的判断:试除法,即用2,3,4,······,根号n去除n,如果能被整除则为合数,不能被整除则为素数。

//哥德巴赫猜想
#include <iostream>
#include <cmath>
using namespace std;
int prime(int n);//判断是否均为素数
 int prime(int i)//判断是否为素数
 {
    int j;
    if(i<=1) return 0;
    if(i==2) return 1;
    for(j=2;j<=(int)(sqrt((double)i));j++)
        if(!(i%j)) return 0;
        return 1;
 }
int main()
{
    int i,n;
    for(i=4;i<=2000;i+=2)//对2000大于2的偶数分解判断,从4开始,每次增2
    {
        for(n=2;n<i;n++)//将偶数i分解为两个整数,一个整数是n,一个是i-n;
            if(prime(n))//判断第一个整数是否均为素数
            if(prime(i-n))//判断第二个整数是否均为素数
        {
            cout<< i <<"="<< n <<"+"<<i-n<<endl;//若均是素数则输出
            break;
        }
        if(n==i)
            cout<<"error "<<endl;
    }
}

算法改进:

        先判断所有分解可能得到的数是否为素数,然后把结果存储,有以下两种方法、

1)用布尔型数组flag[2```````1998]记录分解可能得到的数(2~1998)所有数都不是素数,分解后的值作为下标,调用该数组的值作为下标,调用该数组即可。时间复杂度减少,但空间复杂度增加。

2)用数值型数组data[302]记录2~1998中所有的素数(302个)

·······分解后的值,采用折半查找(素数数组为有序存储)的办法在素数数组中查找,找到就是素数,否则不是。

······不分解,直接在素数数组中找两个素数之和是否为i,如果找到,验证成功。因为素数数组为有序存储,当两个数相加比i大时,不需要再判断后面的数。

算法有两条平行的线速。一个是数据结构(数据对象):数、矩阵、集合、串、排列、图、表达式、分布等。

一个是算法策略:贪心,分治,动态规划,线性规划,搜索等。

这两条线互相独立,同一数据对象上有不同问题,就可以用到不同的算法策略。

总结第一章算法之美:

1)将程序执行次数作为时间复杂度衡量标准。

2)时间复杂度通常用渐进上界符号f(n)表示。

3 ) 衡量算法的好坏通常考察算法的最坏情况。

4)空间复杂度只计算辅助空间。

5)递归算法的空间复杂度要计算递归使用的栈空间。

6)设计算法时尽量避免爆炸级增量复杂度。




  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值