Enter\text{Enter} \looparrowright

题目背景

根据斯诺登事件出的一道水题

题目描述

2013 年 X 月 X 日,俄罗斯办理了斯诺登的护照,于是他混迹于一架开往委内瑞拉的飞机。但是,这件事情太不周密了,因为FBI的间谍早已获悉他的具体位置——但这不是最重要的——最重要的是如果要去委内瑞拉,那么就要经过古巴,而经过古巴的路在美国的掌控之中。
丧心病狂的奥巴马迫降斯诺登的飞机,搜查时却发现,斯诺登杳无踪迹。但是,在据说是斯诺登的座位上,发现了一张纸条。纸条由纯英文构成:Obama is a two five zero.(以 . 结束输出,只有 6 个单词+一个句号,句子开头如没有大写亦为合法)这句话虽然有点无厘头,但是警官陈珺骛发现这是一条极其重要的线索。他在斯诺登截获的一台笔记本中找到了一个 C++ 程序,输入这条句子后立马给出了相对应的密码。陈珺鹜高兴得晕了过去,身为警官的你把字条和程序带上了飞机,准备飞往曼哈顿国际机场,但是在飞机上检查的时候发现——程序被粉碎了!飞机抵达华盛顿只剩5分钟,你必须在这 5 分钟内编写(杜撰)一个程序,免受上司的 10000000000%10 大板。破译密码的步骤如下:
(1)找出句子中所有用英文表示的数字(\leq 20)(≤20),列举在下:
正规:one two three four five six seven eight nine ten eleven twelve thirteen fourteen fifteen sixteen seventeen eighteen nineteen twenty
非正规:a both another first second third。为避免造成歧义,another 算作 11 处理。
(2)将这些数字平方后对 100100 取模,如 00,05,11,19,86,9900,05,11,19,86,99
(3)把这些两位数按数位排成一行,组成一个新数,如果开头为 00,就去 00
(4)找出所有排列方法中最小的一个数,即为密码。

输入格式

一个含有 66 个单词的句子。

输出格式

一个整型变量(密码)。如果没有符合要求的数字出现,则输出 00

输入输出样例

输入 #1

Black Obama is two five zero .

输出 #1

425

分析

首先,我们要将表示数字的单词映射成二位整数。由于需要平方后对 100100 取模,得到的数字在 00009999 之间。我们需要尽量将有前置 00 的数字放在前面,且从小到大排;无前置 00 的数放后面,也从小到大排。例如有数字 [00,05,12,31,03][00,05,12,31,03],显然组成最小的数字是 30512313051231 ,这与映射得到的数字从小到大的排列是一致的。
我们只需要将映射得到的正常整数从小到大排列即可,需要注意的是,输出小于 1010 的数字时,前面要补 $0 $。

代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
#include<string>
#include<cstdio>
#include<algorithm>
#include<iostream>
#include<unordered_map>
#include<vector>
using namespace std;
unordered_map<string,int>val;
void init()//映射
{
val["one"]=1;
val["two"]=4;
val["three"]=9;
val["four"]=16;
val["five"]=25;
val["six"]=36;
val["seven"]=49;
val["eight"]=64;
val["nine"]=81;
val["ten"]=0;
val["eleven"]=21;
val["twelve"]=44;
val["thirteen"]=69;
val["fourteen"]=96;
val["fifteen"]=25;
val["sixteen"]=56;
val["seventeen"]=89;
val["eighteen"]=24;
val["nineteen"]=61;
val["twenty"]=0;
val["a"]=1;
val["both"]=4;
val["first"]=1;
val["second"]=4;
val["third"]=9;
val["another"]=1;
}
int main()
{
int _=6;
string s;
vector<int>ans;
init();
while(_--)//读取6个单词
{
cin>>s;
//如果是0,作为前导0没必要加入
if(val[s]) ans.push_back(val[s]);
}
sort(ans.begin(),ans.end());//从小到大排序
int i;
for(i=0;i<ans.size();i++)
{
if(ans[i]<10&&i) putchar('0');
printf("%d",ans[i]);
}
if(!ans.size()) putchar('0');//没有相应的数字单词
return 0;
}