马克思手稿中的数学题:一共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)设计算法时尽量避免爆炸级增量复杂度。