欧拉计划总结(3)

大家好,我又跟大家见面了!o(≧v≦)o~~在这里给大家说声抱歉,昨天是5.1,所以就提前几天去福州玩了几天,结果就没有及时做好算法,不过回来后我就赶紧补上了。而今天呢,课又比较多,时间比较赶,所以今天就比较晚更。不过对我来说,不管怎么样, 每天一题是我一直的坚持,即使当天没做完,隔天我也会补上。对我来说,当天没做完,隔天补上,当然如果感觉还有余力,那我也会多做点题目,但是算当然还是算当天咯,就像那些网络小说作家一样, 保底一更,爆发多更。回归正传,接下来,我阐述下关于21——30题的我自己的算法思路。
  • problem 21:d(n)定义为n 的所有真因子(小于 n 且能整除 n 的整数)之和。如果 d(a) = b 并且 d(b) = a, 且 a ≠ b, 那么 a 和 b 就是一对相亲数(amicable pair),并且 a 和 b 都叫做亲和数(amicable number)。这道题目是求10000以下的亲和数之和。对这道题目呢,定义一个10000个整形的数组,用for从1循环到10000,再用一个子函数算出当前数值的所有真因子之和赋给当前对应的数值的数组当中。再用for语句i = 2循环整个数组,判断数组当前值d[i]<=10000且要大于i还要判断d[d[I]] == i,求出满足条件的数值之和。
  • problem 22:这道题目是算出给定文件当中,先将文件中名字按字母排序,在计算每个名字的字母值,最后讲字母值与这个名字当前列表位置相乘得到的值,求出所有名字的得到的值之和。一开始说实在的,一开始有思路,知道怎么做,可是按那种静态定义的方法定义的话数据会出错。后来一度跟我好朋友小吴探讨了一番,也没想到什么好的方法。不过有时候当你一直想的时候,他就是想不出来,可一旦放松后,总会在你不经意间想到。于是乎,我在走去教室的路上灵光一闪。用单链表的方法进行排序跟插入。每从文件中获取一个名字,就用单链表的形式一个一个插入到链表当中。不得不说,速度真的很快,不过是在消耗大量空间的基础上换来的。这点还需要改进。
  • problem 23:这道题目是求出所以小于28124的数值中的不能用两个过剩数之和表示的数值之和。我定义两个整形28124的数组分别代表小于2812中的过剩数ab,和一个验证是否能用两个过剩数之和表示的数组other。先用一个for求出28124之内的所有过剩数,然后用两个for嵌套,求出能被两个过剩数之和表示的数值,则另外的一个数组other被标1,在用for判断另一个数组other的每个对应值是否为0,是的话求其28124中的所有数值之和。
  • problem 24:这道题目是算排序的。定义一个全局整形数组num,初始化为0到9先用一个有10个整形的数组x,用2个for嵌套循环表示当前位置总的变化次数,例如X[0]就有9!次变化,for循环数组x,用一个整形rem=999999判断是否大于当前数组的值,是的话求出rem/x[i]的值,用一个子函数实现第i位跟第i+j位交换,而且当中在用2个for嵌套使num数组从i+1位从小到大重新排列。然后rem除以x[i]的余数再赋值给rem,循环整个数组x,答案为数组num,输出整个数组num的值。
  • problem 25:这道是求斐波那契数列中第一个包含1000位的数值是第几项。我就定义了3个数组,分别代表求斐波那契数列前一个数num1,当前数num2,还有相加后的数值num3,用个无限循环whil(1)运算,次数answer+1,for循环加数组num1跟num2给num3,再判断用for循环num3判断每个数值的值是否大于1000000000,是的话当前数组值-掉1000000000,下一个数组值+1,然后判断num[111]>=1 是的话跳出无限循环,输出答案answer,不是的话用for语句将num2的值赋给num1,num3的值赋给num2,一直循环,直到求出答案。
  • problem 26:求1000以内1/d中循环最多的数值d。对于这道题目,我先找出规律,每个能被5跟2整数的数值,当整除到最简算出的循环数值的个数跟原来的数值的循环数是一样的。要计算一个数的循环长度,只要知道该数能被多少长度的9整除就行了。例如3能被9整除,所以她的循环长度为1,7能被999999整除,商的循环体142857,所以长度为6。所以根据这点,先求出一个数值的最简式,再计算循环长度。
  • problem 27:这道题目倒是不难,用两个循环体都从-999循环到1000,分别代表a跟b,次数count初始化为0,然后在嵌套一个for代表连续数字n,写个判断是否为质数的子函数,然后代入题目给的公式的值,判断这个值是否为质数,且要大于0,是的话次数count+1,知道条件不成立跳出n的循环体。判断是否是最大次数,是的话,得出答案answer=a*b。
  • problem 28:对于这道题目,一开始我还没注意看,后来发现题目里有个规律,从正中的1开始顺时针旋转,第一圈的四个角相差都是2,第二圈相差4,第三圈相差6,依次类推,每过一圈相差2。所以i代表每个对角线上的值,初始化为1,while语句循环i<1001*1001,answer等于i之和,len表示每次+的长度,j初始化为0,用个if判断j是不是已经是4次了,是的话len+2,且j-4,最后得出答案answer。
  • problem 29:我是先定义2个大小适当的bool数组use,flag,use的数组都值为false,for从i=2循环到101,判断当前数组use是否为false,是的话,flag数组先全值为false,定义临时整形t保存当前i值,在用for循环use数组,t=t*i,判断t是否大于等于101,是的话跳出循环,不是的话,继续循环,且use的当前数值值为true,循环结束或者跳出当前循环后,再用2个for嵌套,循环flag数组,满足数组条件的值为true,循环结束后,在循环一次flag,answer统计flag为true的个数。
  • problem 30:这道也比较简单,先设计2个子函数,一个将数值转换成字符串,一个将当前值乘5次方输出。for从i=10开始循环到1000000,调用转成字符串的子函数,定义个64位临时整形t,在用for循环整个字符串,将每个字符表示的数值调用5次方的子函数输出,t表示改数组每位数的5次方之和。循环结束后,判断t是否等于当前i值,是的话answer+=i,输出answer。

本来这心得昨天就能写好,可是悲剧的是学校突然断电,吓死我了,还好腾讯有自动保存的功能,不然我还不哭死。

对于我来说,这次写的心得非常费脑筋,因为可以说在做project euler第22题的时候,我就卡住了,这应该叫做瓶颈吧,开始觉得后面的题目越来越难了。例如22题不得不用单链表来做,速度才比较快;24题的时候我一度很死脑筋的想用10个for进行嵌套,结果当然是慢的跟乌龟一样等等。在这当中,我也借鉴了许多网上牛人的博客,看了别人的算法思路,有的一团糟(至少我看得很难受),有的一些算法思路会启发我的灵感,有时候真的会发现一些自己一直都没怎么注重的东西,例如每次看到算法题目,当我理清题意在做题目的时候,总是很死板的想要一个个罗列出一大堆的值,来求证所以会循环到的数值,从来没仔细研究过题目里面到底有没有什么我没注意到的数学上的逻辑。后来在看别人的代码的时候,才发觉自己有多笨,多傻。又或者对于题目,没仔细看好题目,理清题目要求,就盲目做下去。当然由于自己对题目理解错误,导致做出来的答案错误,这点真值得反省反省。

有时候,当你专心致志去做某一件事情,你会发现自己有好多缺点需要纠正。即使你再怎么不想改变,那些事情,这样的生活也会“逼”得你不得不做出改变。正如俞敏洪博客里讲的那样:生活从来都不是一帆风顺的,成功从来都不是唾手可得的。有时候我们觉得在被“逼”着做某些事情时,不必为此感到无奈或懊恼,因为这些事情从长远来看也许不是坏事,比如被老师“逼”着背课文,被同学“逼”着参加活动,被老板“逼”着不断工作,被竞争“逼”着天天学习……也许,适当的逼迫能够把我们的惰性“逼”走,把我们的平庸“逼”走,把我们的勇气“逼”出来,把我们的前途“逼”出来,也把我们的成就感和幸福感“逼”出来。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值