CODY Contest 2020 Project Euler I 全10题

第一题  Problem 230. Project Euler: Problem 1, Multiples of 3 and 5

If we list all the natural numbers below 10 that are multiples of 3 or 5, we get 3, 5, 6 and 9. The sum of these multiples is 23.

Find the sum of all the multiples of 3 or 5 below the input value.

Thank you to Project Euler Problem 1

返回所有在输入值以下的自然数,并且是三或五的倍数之和。

这道题我才用的时向量法,将输入值x以下的所有自然数(1~x1)储存在向量内,分别判断对向量求3余(mod)和5余是否为0,将3余和5余的结果进行或(|而不是||)操作,这样就得到了一个mask向量,0对应表示不为3或5的倍数,1对应值表示是3或5的倍数,然后对x进行索引得到了是3或5的倍数的自然数,然后sum求和即可。

function y = euler001(x)
    x=1:x-1;
    y =sum(x(mod(x,3)==0 | mod(x,5)==0));
end

第二题 Problem 232. Project Euler: Problem 2, Sum of even Fibonacci

Each new term in the Fibonacci sequence is generated by adding the previous two terms. By starting with 1 and 2, the first 10 terms will be:

1, 2, 3, 5, 8, 13, 21, 34, 55, 89, ...

By considering the terms in the Fibonacci sequence whose values do not exceed the input value, find the sum of the even-valued terms.

给定从1 2 开始的斐波那契数列,求不超过输入值并且是偶数的值的和。

想了半天没找到什么有效的方法,比如使用通项公式,或者偶数值的和满足一个公式等等,唯一便捷是发现偶数值项分布满足一定的规律:2的下标是2,8的是5,34的是8,等等,可以推断出第3i+2项为偶数,i为0以上的整数,所以在构造斐波那契数列时判断当前下标除以3是否为2,如果为2就把值加入结果;当然也要加入判断当前值是否大于输入,大于则停止。为了节省空间,用a1 a2 a3三个变量即可实现,不需要使用数组来存储,每次计算a3=a1+a2并判断后,更新a1=a2 ; a2=a3 即可。

function y = euler002(x)
    a1=1;
    a2=2;
    i=3;
    y=2;
    while true
        a3=a1+a2;
        if a3>x
            break
        end
        if mod(i,3)==2
            y=y+a3;
        end
        i=i+1;
        
        a1=a2;
        a2=a3;
    end
end

第三题 Problem 234. Project Euler: Problem 3, Largest prime factor

The prime factors of 13195 are 5, 7, 13 and 29.

What is the largest prime factor of the number being input, input might be uint64 for large numbers, out must be double precision?

Thank you to Project Euler Problem 3

输入值可以看作多个质数的乘积,求最大质数(最开始当作最大因子做了。。。)

第一种方法,matlab可以直接生成一个小于等于n的质数数组,那么对于输入值x,获得质数数据primes(x/2) 然后从最后一位倒序判断是否能整除x,如果满足则他就是最大质数,但是对于第一个样例,matlab:卒。

后边样例还有更大的,所以需要优化。同时,matlab也提供了isprime判断输入值是否为质数,十分便利。所以第二种方法是从x/2往前遍历,判断当前值是否同时满足整除x并且为质数:

k=floor(x/2);
while true
    if mod(x,k)==0 && isprime(k)
        y=k;
        break
    end
end

但是非常耗时。

可以通过短除法来求解:首先对于x,不断除以2直到不能满足整除以2,然后再继续整除3,5  7 11 等等,一直到下一个质数作为除数时,满足该质数的平方大于x,说明当前x已经为质数且不能分解为其他质数的乘积(证明:假设被除数为i,当前为x,并且根据之前的累除,x的因子中不含有小于i的所有质数,所以x的最小因子可能为i,当前还需要进行判定是否能整除,如果x的最小因子为i,那么剩下因子的乘积为x/i,但如果i^2>x,x/i会小于i,和“x的因子中不含有小于i的所有质数”互斥;当前刚刚是能够整除的情况,如果不能整除,i会跳为下一个质数,i会变得更大,x/i变得更小,所以更不能成立。故i^2>x时 x不能分解为其他质数的乘积)

function y = euler003(x)
    i=1;
    while true
       while ~isprime(i)
           i=i+1;
       end
       %找到下一个的质数
       if(i^2>=x)
           y=x;
           return;
       end
       %如果质数的平方大于当前数,说明x已经不能再分解为质数的乘积
       while mod(x,i)==0
           x=x/i;
       end
       %累除
       i=i+1;
    end
end

第四题 Problem 235. Project Euler: Problem 4, Palindromic numbers

A palindromic number reads the same both ways. The largest palindrome made from the product of two 2-digit numbers is 9009 = 91 99.

Find the largest palindrome made from the product of numbers less than or equal to the input number.

Thank you to Project Euler Problem 4

回文数(palindromic)的定义再熟悉不过了,两个两位数的乘积的最大回文数时9009(91*99),求查找由小于或等于输入数字的乘积构成的最大回文。

由于比较笨,没有利用回文数的一些数学性质等等,直接将小于输入x的两个数的所有乘积进行从大到小排序,然后依次判断是否为回文(老暴力了)

function y = euler004(x)
    n=(x:-1:1)'*(x:-1:1);
    n=sort(n(:),'descend');
    for i=1:length(n)
        ret=1;
        s=char(num2str(n(i)));
        for k=1:length(s)/2
            if s(k)~=s(end-k+1)
                ret=0;
                break
            end
        end
        if(ret)
            y=n(i);
            break;
        end
    end
end

第五题 Problem 239. Project Euler: Problem 5, Smallest multiple

2520 is the smallest number that can be divided by each of the numbers from 1 to 10 without any remainder.

What is the smallest positive number that is evenly divisible by all of the numbers from 1 to input number?

Thank you to Project Euler Problem 5

2520是1到10的最小公倍数,求1到x的最小公倍数。matlab提供最小公倍数函数lcm。但是仅支持两个数或两个向量的最小公倍数,不支持多个数的最小公倍数,但是将1~x转为sym格式可以操作:

function y = euler005(x)
  y=lcm(sym(1:x));
  y=double(y);
end

在我的机器上跑木有问题,但是提交上去显示没有double格式对应的sym,那就直接遍历了,每次求之前最小公倍数y和当前数的最小公倍数。

function y = euler005(x)
    y=1;
    for i=2:x
        y=lcm(i,y);
    end
end

老不讲武德了。

第六题 Problem 240. Project Euler: Problem 6, Natural numbers, squares and sums.

The sum of the squares of the first ten natural numbers is,

1^2 + 2^2 + ... + 10^2 = 385 The square of the sum of the first ten natural numbers is,

(1 + 2 + ... + 10)^2 = 55^2 = 3025 Hence the difference between the sum of the squares of the first ten natural numbers and the square of the sum is 3025 - 385 = 2640.

Find the difference between the sum of the squares of the first N (where N is the input) natural numbers and the square of the sum.

Thank you to Project Euler Problem 6

计算1到N的和的平方 与 1到N的平方的和 之前的差值。

第一种方法,列出1到x的向量,分别求向量的和 然后再平方 以及向量点平方后的和  的差值:

x=20;
x=1:x;
y=sum(x)^2-sum(x.^2);

评论区有人说LOOP IS NOT COOL

那好吧,1到x的求和可以用求和公式 x(x+1)/2,1、2^2、3^2、...、n^2的和为x(x+1)(2x+1)/6,前者的平方减去后者最后化简为x(x^2-1)(3n+2)/12。

所以:

function y = euler006(x)
  y = x*(x^2-1)*(3*x+2)/12;
end

第七题 Problem 241. Project Euler: Problem 7, Nth prime

By listing the first six prime numbers: 2, 3, 5, 7, 11, and 13, we can see that the 6th prime is 13.

What is the Nth prime number?

Thank you to Project Euler Problem 7

返回从2开始的第n个质数。如果不根据质数的一些性质等等,那么就只有遍历了:

function y = euler007(x)
    j=0;
    i=2;
    while true
        if isprime(i)
            j=j+1;
        end
        if(j==x)
            y=i;
       
            break;
        end
        i=i+1;
    end
end

第八题 Problem 246. Project Euler: Problem 8, Find largest product in a large string of numbers

Find the greatest product of five consecutive digits in an n-digit number.

7316717653133062491922511967442657474235534919493496983520312774506326239578318016984801869478851843 8586156078911294949545950173795833195285320880551112540698747158523863050715693290963295227443043557 6689664895044524452316173185640309871112172238311362229893423380308135336276614282806444486645238749 3035890729629049156044077239071381051585930796086670172427121883998797908792274921901699720888093776 6572733300105336788122023542180975125454059475224352584907711670556013604839586446706324415722155397 5369781797784617406495514929086256932197846862248283972241375657056057490261407972968652414535100474 8216637048440319989000889524345065854122758866688116427171479924442928230863465674813919123162824586 1786645835912456652947654568284891288314260769004224219022671055626321111109370544217506941658960408 0719840385096245544436298123098787992724428490918884580156166097919133875499200524063689912560717606 0588611646710940507754100225698315520005593572972571636269561882670428252483600823257530420752963450

The large number will be given as a string, 1xn characters.

Thank you to Project Euler Problem 8

在给定的字符串数(例如上边那么长的数,用字符串来储存),求连续五个数的最大乘积。可以直接遍历,或者把连续五个看作一个滑动窗口:假设前八位分别为a b c d e f g h 第一次计算得到a*b*c*d*e,对于步长为1b*c*d*e*f 由于b*c*d*e已经计算过了,如果f大于a,那么b*c*d*e*f的值大于a*b*c*d*e,所以向左滑动一个单位;否则,继续对于步长为2 比较a*b和f*g的大小,后者大则直接滑动两个单位,以此类推,如果步长为4都不满足,直接向右滑动五个单位。其他方法亦可解。

对于边界问题判断比较麻烦,所以在获得输入的字符串长度后再字符串后又加了四个0。

function y = euler008(x)
     n=length(x);
     x(end+1:end+4)='0000';
     y=-Inf;
     i=1;
     while i<=n-4
         temp=double(x(i:i+4))-48;
         y=max(y,prod(temp));
         if (i==n-4)
             break;
         end
         if temp(1)<=double(x(i+5))-48
             i=i+1;
         elseif temp(1)*temp(2)<=(double(x(i+5))-48)*(double(x(i+6))-48)
            i=i+2;
         elseif temp(1)*temp(2)*temp(3)<=(double(x(i+5))-48)*(double(x(i+6))-48)*(double(x(i+7))-48)
             i=i+3;
         elseif temp(1)*temp(2)*temp(3)*temp(4)<=(double(x(i+5))-48)*(double(x(i+6))-48)*(double(x(i+7))-48)*(double(x(i+8))-48)
             i=i+4;
         else
             i=i+5;
         end
     end
end

第九题 Problem 249. Project Euler: Problem 9, Pythagorean numbers

A Pythagorean triplet is a set of three natural numbers, a b c, for which,

a^2 + b^2 = c^2

For example,

3^2 + 4^2 = 9 + 16 = 5^2 = 25.

There exists exactly one Pythagorean triplet for which a + b + c = N (the input).

Find the product abc.

Thank you to Project Euler Problem 9.

毕达哥拉斯(著名的发明家 黑默丁格的偶像)三元数满足a^2+b^2=c^2(这不就是勾股定理的三条边吗),给定输入N,求满足a^2+b^2=c^2并且a+b+c=N的 abc之乘积。(abc均为自然数)联立方程a^2+b^2=c^2和a+b+c=N,N是已知的,所以可以先消去abc其中一项,得到其余两项之间的关系,由于c^2在第一个式子的右端,所以消去c比较简单,得到N^2-2aN-2bN+2ab=0, 所以a=(N^2-2bN)/(2N-2b),遍历b,满足a为整数即可,假设a<=b<c,那么a=(N^2-2bN)/(2N-2b)<=b化简为N^2-4bn+2b^2<=0 即(N-b)^2<=0.5N^2,解得b>=N-sqrt(0.5)N,或者当b=a时带入解得a=N/(sqrt(2)+2),所以b>=N/(sqrt(2)+2),两个是同一个意思,因为c大于b,所以最大b无限接近于c,所以b的上限为N/2,且不可取。遍历b的范围,判断此时a是否为整数,如果为整数计算abc的乘积即可,因为只有一组,所以得到后直接返回。

因为b也要为整数,所以下界要向上取整,上界可不做处理。

function y = euler009(x)
    for b=ceil(x/(sqrt(2)+2)):x/2-1
        a=(x^2-2*b*x)/(2*x-2*b);
        if mod(a,1)==0
            y=a*b*sqrt(a^2+b^2);
            return;
        end
    end
end

第十题 Project Euler: Problem 10, Sum of Primes

The sum of the primes less than or equal to 10 is 2 + 3 + 5 + 7 = 17.

Find the sum of all the primes less than or equal to the input, N.

Thank you Project Euler Problem 10

求小于等于给定数的质数之和。和前几题都很像。(这道题大家标注为easy)

既然easy的话那就来个easy的解法:

function y = euler010(x)
  y = sum(primes(x));
end

幸好测试用例不是特别特别特别大,不至于primes算不出来。

 

相比于前几套题,这套题稍微有点难度,虽然大部分的题可以鲁棒地解,一些题根据质数等的一些特性会有一些很好的解法,比直接循环等可能好得多,由于对这边知识不太够,所以就告辞。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值