eBash

It is not the mountain we conquer but ourselves

Project Euler Problem 28

| Comments

Table of Contents

1 Problem

Starting with the number 1 and moving to the right in a clockwise direction a 5 by 5 spiral is formed as follows:

21 22 23 24 25
20  7  8  9 10
19  6  1  2 11
18  5  4  3 12
17 16 15 14 13

It can be verified that the sum of the numbers on the diagonals is 101.

What is the sum of the numbers on the diagonals in a 1001 by 1001 spiral formed in the same way?

2 Solution

观察数字1,3,5,7,9,13,17,21,25,易知对角线数字递增规律为连续4个差2(3 + 2 = 5),连续4个差4(9 + 4 =13)…连续4个差(n-1);

当然我们也可以从中得出递推关系,观察右上对角线数字,1, 9, 25为1, 3, 5的平方,所有我们很容易知道f(n)的最右上的数字为 \(n^2\),则f(n)为f(n-2)加上最外围四个数字:
f(n) = f(n - 2) + 4 \(n^2\) - 6(n - 1);
一个简单的等差数列,最后求得:
\begin{eqnarray*} f(n) = \frac{2}{3}(n - 1)^{3} + \frac{5}{2}(n - 1)^2 + \frac{13}{3}(n - 1) + 1 \end{eqnarray*}

3 Answer

669171001

Source:C++

Project Euler Problem 19

| Comments

Table of Contents

1 Problem

You are given the following information, but you may prefer to do some research for yourself.

1 Jan 1900 was a Monday.
Thirty days has September,
April, June and November.
All the rest have thirty-one,
Saving February alone,
Which has twenty-eight, rain or shine.
And on leap years, twenty-nine.
A leap year occurs on any year evenly divisible by 4, but not on a century unless it is divisible by 400.

How many Sundays fell on the first of the month during the twentieth century (1 Jan 1901 to 31 Dec 2000)?

2 Solution

很直接的,查下表1901/1/1是星期二,此时设表示周几的变量numOfDay = 2,那么1901/2/1是周几?只要numOfDay加上一月份的天数31,再模7得5知为周五.依此法检测1901~2000每月第一天是周几。注意:别忘了2月份的天数需要是否闰年的判断.

3 Answer

171

Source:C++

Project Euler Problem 48

| Comments

Table of Contents

1 Problem

The series, \(1^1\) + \(2^2\) + \(3^3\) + … + \(10^{10}\) = 10405071317.

Find the last ten digits of the series, \(1^1\) + \(2^2\) + \(3^3\) + … + \(1000^{1000}\).

2 Solution

对于直接大数据操作的,直接运算即可,不支持的只要对结果用模取最后10位进行操作即可.

3 Answer

9110846700

Source:C++

Project Euler Problem 22

| Comments

Table of Contents

1 Problem

Using names.txt (right click and ‘Save Link/Target As…’), a 46K text file containing over five-thousand first names, begin by sorting it into alphabetical order. Then working out the alphabetical value for each name, multiply this value by its alphabetical position in the list to obtain a name score.

For example, when the list is sorted into alphabetical order, COLIN, which is worth 3 + 15 + 12 + 9 + 14 = 53, is the 938th name in the list. So, COLIN would obtain a score of 938 53 = 49714.

What is the total of all the name scores in the file?

2 Solution

没什么好说的,先读入数据,然后排序,最后进行计算,效率关键在于排序.

3 Answer

871198282

Source:C++

Project Euler Problem 21

| Comments

Table of Contents

1 Problem

Let d(n) be defined as the sum of proper divisors of n (numbers less than n which divide evenly into n). If d(a) = b and d(b) = a, where a b, then a and b are an amicable pair and each of a and b are called amicable numbers.

For example, the proper divisors of 220 are 1, 2, 4, 5, 10, 11, 20, 22, 44, 55 and 110; therefore d(220) = 284. The proper divisors of 284 are 1, 2, 4, 71 and 142; so d(284) = 220.

Evaluate the sum of all the amicable numbers under 10000.

2 Solution

按题意暴力求解,但我们还是能在细节进行一些优化.

  1. 我们只寻找amicable pair numbers中小的数,但相加时把两者都加上.
  2. getDivisorSum的优化
    1. 直观的,循环只要到sqrt(n)就行,因为除数是对应的,n = a * b,由反证法易知一数小于等于sqrt(n),另一数大于等于sqrt(n);
    2. 我们考虑求质数,公式( \ref{ref1} ),公式( \ref{ref2} )明显成立,公式( \ref{ref3} )左右两边展开相等可证
      getDivisorSum(p1*p2*..p_n) = 1+ p1 + p2 + ... pn + p1p2 + .. + p(n-1)p(n) + ... + p1p2..pn 
                                 = (1 + p1)(1 + p2)...(1 + pn) 
                                 = getDivisorSum(p1) * getDivisorSum(p2) * ... * getDivisorSum(pn)
      
\begin{eqnarray} getDivisorSum(p) = (p + 1)\label{ref1}\ \end{eqnarray} \begin{eqnarray} getDivisorSum(p^i) = 1 + p^2 + … + p^i = \frac{p^{i+1}-1}{p-1}\label{ref2}\ \end{eqnarray} \begin{eqnarray} getDivisorSum(p1*p2*..p_n) = getDivisorSum(p1) * getDivisorSum(p2) * …\label{ref3} \end{eqnarray}

3 Answer

31626

Source:C++

如何阅读一本书

| Comments

做事要讲究方法,读书也是如此.自己虽然读过的书不少,但感觉都没有内化.于是找到了这本书如何阅读一本书 (HOW TO READ A BOOK)

本书的作者是莫提默·J. 艾德勒,看简介应该是很有学问的人.他系统地介绍了如何阅读一本书.总体行文可以说啰嗦,好听点叫细致,其大体方法从目录大纲即可得知.

就我个人而言,虽然从来没有系统化地总结过自己的阅读方法,但大体上与本书作者不谋而合。
本书将阅读分为四个层次:

  1. 基础阅读
  2. 检视阅读
  3. 分析阅读
  4. 主题阅读

简单地说,基础阅读,大概为基础识字等准备阶段,识字理解基本意思即可;检视阅读为略读或粗读,分析阅读为阅读理解,主题阅读则为多本书对某一主题进行分析比较.
我认为,作为高中生至少应该掌握到分析阅读,大学生至少应该掌握所有的层次.

这本书于我的价值最大的倒不是所谓的阅读技巧(我已经基本掌握,只是没有系统化的去理解),而是作者的一些理念.

阅读越主动,效果越好

阅读心不在焉,神游其外,陷入茫茫之中,不知书中所言,对内容逆来顺受,当然不能希望能有多大的收获了.

所谓阅读速度,理想上来说,不只是要能读得快,还要能用不同的速度来阅读—要知道什么时候用 什么样的速度是恰当的

现在呀,凡事都求快,社会确实浮躁了些。我常常看到一些人晒出自己一年读了几百本书,然后对比自己一年的阅读量,当真是十分的励志!可惜我没法询问当事人阅读的效果.快当然是好,但过犹不及.一些难懂,经典的书籍是需要慢去理解的,一些片段是需要慢去欣赏的.因为就没必要一味的追求数量.当今是信息大爆炸的时代,固然对信息的快速处理(快速阅读)的技巧十分重要,但对信息的筛选,有效的处理却更重要,现在可没人能穷尽所有书籍了.我秉持着一种信念”精优于胜”,一般情况下泛泛而读一万本也比不上读精一本书.

不管对于有经验的还是缺乏阅读技巧的读者,这本书还是有所价值的.

Project Euler Problem 18

| Comments

1 Problem

By starting at the top of the triangle below and moving to adjacent numbers on the row below, the maximum total from top to bottom is 23.

3
7 4
2 4 6
8 5 9 3

That is, 3 + 7 + 4 + 9 = 23.

Find the maximum total from top to bottom of the triangle below:

75
95 64
17 47 82
18 35 87 10
20 04 82 47 65
19 01 23 75 03 34
88 02 77 73 07 63 67
99 65 04 28 06 16 70 92
41 41 26 56 83 40 80 70 33
41 48 72 33 47 32 37 16 94 29
53 71 44 65 25 43 91 52 97 51 14
70 11 33 28 77 73 17 78 39 68 17 57
91 71 52 38 17 14 91 43 58 50 27 29 48
63 66 04 68 89 53 67 30 73 16 69 87 40 31
04 62 98 27 23 09 70 98 73 93 38 53 60 04 23

NOTE: As there are only 16384 routes, it is possible to solve this problem by trying every route. However, Problem 67, is the same challenge with a triangle containing one-hundred rows; it cannot be solved by brute force, and requires a clever method! ;o)

2 Solution

2.1 Brute Force

直接的方法就是brute force,但对于大数据量时速度会很慢.
对于n层高,共有 \(\frac{(n+1)n}{2}\) 个数字,由归纳法易知需要穷尽 \(2^{n-1}\) 条路径,每条路径上有n个数字,需要 \(\Theta(2^{n-1}n)\) 的时间, 易知数字总数m = \(\frac{(n + 2)(n + 1)}{2}\) ,则 m = \(\frac{\sqrt{1+8m}-3}{2}\),代入其中即得关于输入个数m的时间复杂度.

2.2 递归

2.2.1 分析

\(p_{i}\) 为第i个数字到最末层相邻数字相加最大值, \(a_{i}\) 为第i个数字的值, \(i\in(0,\frac{(n + 1)(n + 2)}{2})\)
题目所求为 \(p_{0}\) 的值,易知 \(p_{0}\) = max(\(p_{1}\), \(p_{2}\)) + \(a_{0}\) , \(p_{1}\) = max(\(p_{3}\), \(p_{4}\)) + \(a_{1}\) ,…
设共有n层高(从0开始),则对于i层(第 \(\frac{(i + 1)i}{2}\) ~ \(\frac{(i + 1)i}{2} + i\) 个数),以下等式成立:
\(p_{j}\) = max(\(p_{j + i + 1}\), \(p_{j + i + 2}\)) + \(a_{j}\) j \(\in[\frac{(i + 1)i}{2}\) , \(\frac{(i + 1)i}{2} + i]\)
\(p_{j}\) = \(a_{j}\) j \(\in[\frac{(n + 1)n}{2}\) , \(\frac{(n + 1)n}{2} + n]\)
对于n层高,其时间复杂度为 \(\Theta(\frac{(n+1)n}{2})\),易知数字总数m = \(\frac{(n + 2)(n + 1)}{2}\) ,则转换知对于输入个数m,其时间复杂度为 \(\Theta(m)\)

2.2.2 例子

对于原题中的例子其递归调用过程如下:

\(p_0\) = max(\(p_1\), \(p_2\)) + 3
\(p_1\) = max(\(p_3\), \(p_4\)) + 7
\(p_3\) = max(\(p_6\), \(p_7\)) + 2
\(p_6\) = 8
\(p_7\) = 5
\(p_3\) = 8 + 2 = 10
\(p_4\) = max(\(p_7\), \(p_8\)) + 4
\(p_8\) = 9
\(p_4\) = 9 + 4 = 13
\(p_1\) = 9 + 4 + 7 = 20
\(p_2\) = max(\(p_4\), \(p_5\)) + 4
\(p_5\) = max(\(p_8\), \(p_9\)) + 6
\(p_9\) = 3
\(p_5\) = 9 + 6 = 15
\(p_2\) = 9 + 6 + 4 = 19
\(p_0\) = 9 + 4 + 7 + 3 = 23

可以近似把所有数字看作一棵树,则为前序遍历,后序计算

2.3 Bottom-Up

2.3.1 分析

我们将上述递归算法转换为迭代,过程如下:
第n层时, \(p_{j}\) = \(a_{j}\) j \(\in[\frac{(n + 1)n}{2}\) , \(\frac{(n + 1)n}{2} + n]\)
第i层, \(p_{j}\) = max(\(p_{j + i + 1}\), \(p_{j + i + 2}\)) + \(a_{j}\) j \(\in[\frac{(i + 1)i}{2}\) , \(\frac{(i + 1)i}{2} + i]\)
与递归大抵类似.

对于输入个数n,其时间复杂度与递归类似为 \(\Theta(n)\), 如果 \(p_i\) 与 \(a_i\) 使用同一数组,则其空间复杂度为 \(\Theta(1)\)

2.3.2 例子

其计算过程如下:

   3                3             3          23
  7 4             7  4         20   19  
 2 4 6    ->    10 13 15   ->           ->  
8 5 9 3       

3 Answer

1074

Source:C++迭代 C++递归

Project Euler Problem 17

| Comments

Table of Contents

1 Problem

If the numbers 1 to 5 are written out in words: one, two, three, four, five, then there are 3 + 3 + 5 + 4 + 4 = 19 letters used in total.

If all the numbers from 1 to 1000 (one thousand) inclusive were written out in words, how many letters would be used?

NOTE: Do not count spaces or hyphens. For example, 342 (three hundred and forty-two) contains 23 letters and 115 (one hundred and fifteen) contains 20 letters. The use of “and” when writing out numbers is in compliance with British usage.

2 Solution

我们知道<1000的都可由,one,two…ninteen,twenty,thirty…ninety,hundred,and 这些英文字母表达出来,并将one~nineteen的字母数保存在数组 a[19]={3, 3, 5, 4, 4, 3, 5, 5, 4, 3, 6, 6, 8, 8, 7, 7, 9, 8, 8} 中,twenty,thirty..ninety的字母数保存在数组 b[8]={6, 6, 5, 5, 5, 7, 6, 6} 中,简单分类计算sum:

  1. \(i\in[1,20)\)
    sum = sum+ a[i - 1]
  2. \(i\in[20,100)\)
    1. sum = sum + b[i / 10 - 2] \(i\in\) {20,30,..90}
    2. sum = sum + b[i / 10 - 2] + a[i % 10 - 1] \(i\in\) {21,22,…99}
  3. \(i\in[100,1000)\)
    1. sum = sum + a[i / 100 - 1] + len(“hundred”) \(i\in\) {100,200,300..900}
    2. sum = sum + a[i / 100 - 1] + len(“hundred”) + len(“and”) + a[i % 100 - 1]; \(i\in\) {101-119,201-219,…901-919}
    3. sum = sum + a[i / 100 - 1] + len(“hundred”) + len(“and”) + b[i / 10 % 10 - 2]; \(i\in\) {120,130,140..990}
    4. sum = sum + a[i / 100 - 1] + len(“hundred”) + len(“and”) + a[i % 10 - 1] + b[i / 10 % 10 - 2]; \(i\in\) {121,122…999}
  4. \(i = 1000\)
    sum = sum + len(“one”) + len(“thousand”);

3 Answer

21124

Source:C++

Project Euler Problem 15

| Comments

Table of Contents

1 Problem

Starting in the top left corner of a 2*2 grid, and only being able to move to the right and down, there are exactly 6 routes to the bottom right corner.

http://projecteuler.net/project/images/p_015.gif

How many such routes are there through a 20*20 grid?

2 Solution

设左上角坐标为(0,0),右下角坐标为(n,n),则有

递归式:

path(i, j) = path(i-1, j) + path(i, j-1)

因为只能向右或向下运动,故处于某点(i,j)时的路径数为与此点相邻的(i-1,j)和(i,j-1)路径数之和.

递归终止条件为当点位于最右(最下)时,其路径数是唯一的,只能一直向下(向右),即path(n,i) = 1, path(i,n) = 1

从数学的角度看,只需要用到高中的排列组合.从源到目的地共需要移动n + n步,求其路径数即求哪些步骤向右哪些步骤向下,即:

path = \(C_{2n}^{n}\)

当然对于a*b的格子路径数也是同样的做法

3 Answer

137846528820

Source:C++

Project Euler Problem 25

| Comments

Table of Contents

1 Problem

The Fibonacci sequence is defined by the recurrence relation:

\(F_{n}\) = \(F_{n-1}\) + \(F_{n-2}\) , where \(F_1\) = 1 and \(F_2\) = 1. Hence the first 12 terms will be:

\(F_1\) = 1
\(F_2\) = 1
\(F_3\) = 2
\(F_4\) = 3
\(F_5\) = 5
\(F_6\) = 8
\(F_7\) = 13
\(F_8\) = 21
\(F_9\) = 34
\(F_{10}\) = 55
\(F_{11}\) = 89
\(F_{12}\) = 144
The 12th term, \(F_{12}\) , is the first term to contain three digits.

What is the first term in the Fibonacci sequence to contain 1000 digits?

2 Solution

没什么好说的,大数据处理

3 Answer

4782

Source:C++