题解:洛谷 P1603 斯诺登的密码

【题目来源】

洛谷:P1603 斯诺登的密码 - 洛谷

【题目描述】

\(2013\)\(X\)\(X\) 日,俄罗斯办理了斯诺登的护照,于是他混迹于一架开往委内瑞拉的飞机。但是,这件事情太不周密了,因为 FBI 的间谍早已获悉他的具体位置——但这不是最重要的——最重要的是如果要去委内瑞拉,那么就要经过古巴,而经过古巴的路在美国的掌控之中。

丧心病狂的奥巴马迫降斯诺登的飞机,搜查时却发现,斯诺登杳无踪迹。但是,在据说是斯诺登的座位上,发现了一张纸条。纸条由纯英文构成:Obama is a two five zero.(以 . 结束输出,只有 \(6\) 个单词 + 一个句号,句子开头如没有大写亦为合法)这句话虽然有点无厘头,但是警官陈珺骛发现这是一条极其重要的线索。他在斯诺登截获的一台笔记本中找到了一个 C++ 程序,输入这条句子后立马给出了相对应的密码。陈珺鹜高兴得晕了过去,身为警官的你把字条和程序带上了飞机,准备飞往曼哈顿国际机场,但是在飞机上检查的时候发现——程序被粉碎了!飞机抵达华盛顿只剩 \(5\) 分钟,你必须在这 \(5\) 分钟内编写(杜撰)一个程序,免受上司的 \(10000000000 \ mod\  10\) 大板。破译密码的步骤如下:

(1)找出句子中所有用英文表示的数字 (\(\le 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 算作 \(1\) 处理。

(2)将这些数字平方后对 \(100\) 取模,如 \(00,05,11,19,86,99\)

(3)把这些两位数按数位排成一行,组成一个新数,如果开头为 \(0\),就去 \(0\)

(4)找出所有排列方法中最小的一个数,即为密码。

【输入】

一个含有 \(6\) 个单词的句子。

【输出】

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

【输入样例】

Black Obama is two five zero .

【输出样例】

425

【算法标签】

《洛谷 P1603 斯诺登的密码》 #模拟# #字符串# #排序# #洛谷原创#

【代码详解】

#include <bits/stdc++.h>  // 包含标准库头文件(万能头文件)
using namespace std;      // 使用标准命名空间

int main()
{
    int a[10], k = 0;     // 定义数组a存储处理后的数字,k为计数器
    // 数字单词对照表
    string dc[] = {"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"};
    // 对应数字值
    int dn[] = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,1,2,1,1,2,3};
    string s;              // 定义字符串:存储输入的单词

    // 处理6个输入单词
    for (int j = 1; j <= 6; j++) 
    {
        cin >> s;         // 输入单词
        // 在单词表中查找匹配
        for (int i = 0; i < 26; i++) 
        {
            if (s == dc[i])  // 如果找到匹配的数字单词
            {
                int x = dn[i];  // 获取对应数字
                x = x * x % 100;  // 数字平方后取最后两位
                a[k++] = x;     // 存储到数组a中
            }
        }
    }

    // 如果没有找到任何数字单词,输出0并结束
    if (k == 0) 
    {
        cout << 0;
        return 0;
    }

    sort(a, a + k);        // 对数组a中的数字进行升序排序

    // 跳过前导零(如果有)
    int st = 0;
    while (a[st] == 0 && st < k) 
    {
        st++;
    }

    // 输出结果(第一个数字不带前导零,后面的数字保持两位数格式)
    printf("%d", a[st]);   // 输出第一个非零数字
    for (int i = st + 1; i < k; i++) 
    {
        printf("%02d", a[i]);  // 输出后续数字(保持两位数)
    }

    return 0;              // 程序正常结束
}

【运行结果】

Black Obama is two five zero .
425
posted @ 2026-02-16 16:09  团爸讲算法  阅读(2)  评论(0)    收藏  举报