时间限制 空间限制
1000 ms 65536 KB

# 题目描述

输出整数 nn 的英文。

# 输入格式

不定行输入,每行一个整数 nn0n23110 \le n \le 2^{31} − 1

# 输出格式

对于每组输入,输出一行 nn 的英文,所有单词首字母大写,每个单词之间有 11 个空格。

不需要加逗号或者 And

# 输入样例

123
12345
1234567

# 输出样例

One Hundred Twenty Three
Twelve Thousand Three Hundred Forty Five
One Million Two Hundred Thirty Four Thousand Five Hundred Sixty Seven

# 提示

以下介绍英语中对自然数的表示,有英语基础的同学可以忽略。

以下定义集合 Digit={0,1,2,3,4,5,6,7,8,9}\text {Digit} = \{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 \} 为自然数集的子集,使用具有上划线的数表示这个自然数在字面上是由多个变元或常元直接拼而成的量、并且英文表示的拼接指两个单词中间由一个空格相连。

  • [0,99][0, 99] 的表示

下表中列出了一些特殊数的表示。

数字 对应的单词 整数 对应的单词 整十数 对应的单词
00 Zero
11 One 1111 Eleven 1010 Ten
22 Two 1212 Twelve 2020 Twenty
33 Three 1313 Thirteen 3030 Thirty
44 Four 1414 Fourteen 4040 Forty
55 Five 1515 Fifteen 5050 Fifty
66 Six 1616 Sixteen 6060 Sixty
77 Seven 1717 Seventeen 7070 Seventy
88 Eight 1818 Eighteen 8080 Eighty
99 Nine 1919 Nineteen 9090 Ninety

对于一般数,即大于 2020 的、个位不为 00 的两位数,其表示由十位数对应的整十数的表示和个位数的表示拼接而成,即:对于大于 2020 的非整十数 ab=10×a+b,a,bDigit,ab0,a2\overline {ab} = 10 \times a + b, a, b \in \text {Digit}, ab \not = 0, a \ge 2,总可以先读 a0=10×a\overline {a0} = 10 \times a 的表示,再读 bb 的表示。

  • [100,999][100,999] 的表示

所有的三位数都可以表示为 abc,a,b,cDigit,a0\overline {abc}, a, b, c \in \text {Digit}, a \not = 0 的形式,其表示由 aa 的表示、 Hundredbc\overline {bc} 的表示拼接而成,如果 b0b \not = 0 或者 c0c \not = 0 。否则,其表示为 aa 的表示和 Hundred 拼接而成。

  • 更大正整数的表示

所有的位数大于等于 44 的无前导零的正整数都可以从低位向高位每 33 位一节截断。从高位节向低位节,将每节的 33 位数或具有前导零的 22 位数或 11 位数表示拼接起来,并再拼接表示当前节数的单词,即可得到该正整数的表示。特别地,如果一节中的 33 位数字全为 00,那么直接跳过这一节,不进行任何拼接。下表中给出了本题可能需要用到的表示当前节数的单词。

从低位向高位数的节数 对应的单词
11 无单词,不需要拼接
22 Thousand
33 Million
44 Billion
5\ge 5 本题不需要用到

# 题解:模拟

没得说,还是模拟。细节比较多,但都在提示里体现出来了,严格按照以上规则模拟即可。

参考代码:

#include <stdio.h>
#include <stdbool.h>
const char en[20][15] = 
{
    "Zero", 
    "One", 
    "Two", 
    "Three", 
    "Four", 
    "Five", 
    "Six", 
    "Seven", 
    "Eight", 
    "Nine", 
    "Ten", 
    "Eleven", 
    "Twelve", 
    "Thirteen", 
    "Fourteen", 
    "Fifteen", 
    "Sixteen", 
    "Seventeen", 
    "Eighteen", 
    "Nineteen"
} ;
const char bin[8][15] = 
{
    "Twenty", 
    "Thirty", 
    "Forty", 
    "Fifty", 
    "Sixty", 
    "Seventy", 
    "Eighty", 
    "Ninety"
} ;
const char mul[3][15] = 
{
    "Thousand", 
    "Million", 
    "Billion"
} ;
int n;
void print(int x, bool printZero, int mulPos)
{
    if (x == 0 && printZero)
    {
        printf("Zero ");
        return;
    }
    if (x >= 1000000000)
    {
        print(x / 1000000000, false, 2);
        print(x % 1000000000 / 1000000, false, 1);
        print(x % 1000000 / 1000, false, 0);
    }
    else if (x >= 1000000)
    {
        print(x / 1000000, false, 1);
        print(x % 1000000 / 1000, false, 0);
    }
    else if (x >= 1000)
        print(x / 1000, false, 0);
    
    x %= 1000;
    if (x <= 19)
    {
        if (x > 0)
            printf("%s ", en[x]);
    }
    else if (x < 100)
    {
        printf("%s ", bin[x / 10 - 2]);
        
        if (x % 10)
            printf("%s ", en[x % 10]);
    }
    else
    {
        printf("%s Hundred ", en[x / 100]);
        print(x % 100, false, -1);
    }
    if (mulPos >= 0 && x != 0)
        printf("%s ", mul[mulPos]);
    
    return;
}
int main()
{
    // freopen("I.in", "r", stdin);
    // freopen("I.out", "w", stdout);
    while (~scanf("%d", &n))
    {
        print(n, true, -1);
        puts("");
    }
    return 0;
}