Project Euler 1-5题

第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都会是质数。
利用反证法:
  假设当前枚举到的合数 i num的因子,那么 i 一定可以表示为若干个小于i的质数的乘积,并且 nummodi==0
  所以容易得到 nummodpi==0 其中 pi i 的一个质因子,且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;
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值