原题链接:http://projecteuler.net/problem=17
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.
题目大意是:
如果用英文写出数字1到5: one, two, three, four, five, 那么一共需要3 + 3 + 5 + 4 + 4 = 19个字母。
如果数字1到1000(包含1000)用英文写出,那么一共需要多少个字母?
注意: 空格和连字符不算在内。例如,342 (three hundred and forty-two)包含23个字母; 115 (one hundred and fifteen)包含20个字母。"and" 的使用与英国标准一致。解法1:
1.先初始化1~20,30,40,50,60,70,80,90,100,1000这些数字对应的英文的长度的字典
2.对于1~20的英文字符的长度,直接从第1步的字典里取得其长度
3.对于21~99,则分解成两部分,一部分是个位数,可从第1步的字典取得其长度,另一部分是这个数减去个位数的值,亦从第1步的字典里取得其长度
4.对于100~999的number,也要分解成两部分,一部分是a,其中a=100n,0
5.对于1000,直接从第1步的字典里取得其长度
6.求和
php代码如下:
3, //one
2 => 3, //two
3 => 5, //three
4 => 4, //four
5 => 4, //five
6 => 3, //six
7 => 5, //seven
8 => 5, //eight
9 => 4, //nine
10 => 3, //ten
11 => 6, //eleven
12 => 6, //twelve
13 => 8, //thirteen
14 => 8, //fourteen
15 => 7, //fifteen
16 => 7, //sixteen
17 => 9, //seventeen
18 => 8, //eighteen
19 => 8, //nineteen
20 => 6, //twenty
30 => 6, //thirty
40 => 5, //forty
50 => 5, //fifty
60 => 5, //sixty
70 => 7, //seventy
80 => 6, //eighty
90 => 6, //ninety
100 => 7, //hundred
1000 => 8, //thousand
);
function get_letter_num_of_number_which_under_100($number, $dict) {
$letter_num = 0;
if ($number <= 20) {
$letter_num = $dict[$number];
} elseif ($number < 100) {
$mod = $number % 10;
if ($mod == 0) {
$letter_num = $dict[$number - $mod];
} else {
$letter_num = $dict[$number - $mod] + $dict[$mod];
}
}
return $letter_num;
}
function get_letter_num_of_number_which_between_100_and_999($number, $dict) {
$letter_num = 0;
$h = intval($number / 100);
$remain = $number - ($h * 100);
$letter_num+=$dict[$h] + $dict[100];
if ($remain > 0) {
$letter_num+=3; //and
$letter_num+=get_letter_num_of_number_which_under_100($remain, $dict);
}
return $letter_num;
}
$up = 1000;
$letter_num = 0;
for ($i = 1; $i <= $up; $i++) {
if ($i < 100) {
$letter_num+=get_letter_num_of_number_which_under_100($i, $dict);
} elseif ($i < 1000) {
$letter_num+=get_letter_num_of_number_which_between_100_and_999($i, $dict);
} else {
$letter_num+=$dict[1] + $dict[1000];
}
}
echo $letter_num;