Project Euler 1-5题

来源:互联网 发布:mac safari总是崩溃 编辑:程序博客网 时间:2024/05/04 02:47

第1题

这里写图片描述
题目来源ProjectEuler

这个题求的是严格小于1000的数中,是3或5的倍数的数的和。(刚开始理解错below的意思了,把1000算进去了,尴尬)

int main(){    int ans=0;    for (int i=1;i<1000;i++){        if (i%3==0||i%5==0){            ans+=i;        }    }    cout<<ans<<endl;    return 0;}



第2题

这里写图片描述
题目来源ProjectEuler

这个题是求斐波那契数列中所有小于4000000的值为偶数的项的和。所以暴力扫一遍就好了,如果要计算复杂度,可以将斐波那契看成一个q>1.5的等比数列,所以复杂度是log级别的。
但是实现的时候,我利用了f&1==0来判断偶数,然而在C++里==的优先级高于&,结果就变成了恒假的判定条件了,输出为0,后来给加上了括号就好了。我以前居然没被这个坑到过?
运算符优先级详情请参考cppreference

int main(){    int f0=1,f1=1,f=1;    long long ans=0;    while(f<=4000000){        if((f&1)==0)    ans+=f;        f0=f1;f1=f;        f=f1+f0;    }    cout<<ans<<endl;    return 0;}



第3题

这里写图片描述
题目来源ProjectEuler

这个题是求600851475143的最大质因子。
复杂度nlogn
我们从枚举2到n的数,记为i,如果nummodi==0那么就将num的所有为i的因子都除掉。这个时候,我们会执行除法操作的所有i都会是质数。
利用反证法:
  假设当前枚举到的合数inum的因子,那么i一定可以表示为若干个小于i的质数的乘积,并且nummodi==0
  所以容易得到nummodpi==0其中pii的一个质因子,且pi<i
  又因为我们去掉原数的所有小于i的质因子后得到num,那么显然nummodpi!=0,与第二步中的式子矛盾。
  所以若nummodi==0,则i必为质数。
那么我们记录过程中的最大质因子ans,以及最后的num。首先一个数n不会有两个>n的质因数,因为这两个质因数的积就大于n本身了。所以最后剩下的num要不为1要不就是>n的那个质因子。结果就是max(ans,num)

int main(){    long long num=600851475143ll;    long long ans;    for (int i=2;i*i<=num;i++){        if (num%i==0)   ans=i;        while(num%i==0) num/=i;    }    cout<<max(num,ans)<<endl;    return 0;}



第4题

这里写图片描述
题目来源ProjectEuler

这个题是求所有的三位数的乘积中的最大回文数。
所以什么都不用管,直接O(n2)暴力就好了,虽然check还是会有一个log的复杂度,但是很小无伤大雅。
枚举所有三位数的乘积,记录最大的回文数。

bool check(int x){    int s[10],cnt=-1;    while(x){        ++cnt;        s[cnt]=x%10;        x/=10;    }    for (int i=1;i<=cnt;i++){        if (s[i]!=s[cnt-i]) return false;    }    return true;}int main(){    int ans=0;    for (int i=999;i>=100;i--){        for (int j=999;j>=100;j--){            if (check(i*j)){                ans=max(ans,i*j);            }        }    }    cout<<ans<<endl;    return 0;}



第5题

这里写图片描述
题目来源ProjectEuler

这题是求最小的一个数num,满足nummodi==0,i[1,20]
换一个角度思考,nummodi==0表示什么呢?
我们令
num=py11py22pynn
i=pzi11pzi22pzinn
其中p为质数
所以yj=max(zij),i[1,20]
这样结论就出来了,只要将1至20每个数分解质因数,记录zij的最大值zmax,将ans=pzmaxi
当然求每个质数在[1,20]之间最大幂,最后都乘进ans也是可以的。

int occ[25][25];int main(){    int n=20;    for (int i=2;i<=n;i++){        for (int tmp=i,j=2;j<=i;j++){             while(tmp%j==0){                 occ[i][j]++;                 tmp/=j;             }             occ[0][j]=max(occ[0][j],occ[i][j]);        }    }    long long ans=1;    for (int i=2;i<=n;i++){        while(occ[0][i]--){            ans*=i;        }    }    cout<<ans<<endl;    return 0;}
原创粉丝点击