1 条题解

  • 1
    @ 2023-10-28 11:39:48

    点击前往博客阅读体验更佳

    题目背景

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

    题目描述

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

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

    (1)找出句子中所有用英文表示的数字(20\leq 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)找出所有排列方法中最小的一个数,即为密码。

    // 数据已经修正 By absi2011 如果还有问题请联系我

    输入格式

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

    输出格式

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

    输入输出样例

    输入 #1

    Black Obama is two five zero .
    

    输出 #1

    425
    

    分析

    数据咋骂人呢

    先一个个输入单词与题目给出的 26 个单词匹配,string 类型可以直接使用逻辑运算符 == 进行判断(C++ 选手谁闲着没事用 char 数组啊);

    由于已经知道单词数量是 66 个并不需要用到 while 循环(输入字符串的情况下 cin 的返回值情况我也不清楚)

    一些问题

    为什么样例输出不是 245 或者 254

    25和4组成的最小数不是254吗,为什么样例给的425?

    Black Obama is two five zero .

    zero 是不算数的!

    因此我们从六个单词中只能提取出两个:twofive

    转换成数字就是 2255

    然后我们算出它们的平方。

    22=42^2=4

    55=255^5=25

    100100 取模后结果是 04042525,因为题目说

    把这些 两位数 按数位排成一行

    并且给出了 00,05 这两个例子

    有两种排列方法,因为 04250425 开头为 00,去掉开头的 00 之后就是 425425,比另一个排列 25042504

    所以这个所有排列方法中最小的一个数是 425425,而不是 25042504

    把这些两位数按数位排成一行,组成一个新数

    我感觉中间那三个字是多余的...不仅不能帮助理解反而可能误导选手

    只能得 20 分?

    放一下我下载的测试点#2 的数据(请勿用于打表):

    You are a three eight pig .
    
    10964
    

    我得了 20 分的程序在这个测试点上给出的答案是 1964,也就是忽略了所有 0,但实际上只能忽略开头那个。

    如果开头为 0,就去 0。

    记得排序。

    if(num[0]) cout<<num[0];
    for(int i=1;i<cnt;i++){
        if(num[i]>10) cout<<num[i];
        else cout<<'0'<<num[i];
    }
    

    忘了没有任何单词匹配的情况

    可能就我没看清题?

    直接输出 0 后结束程序即可。

    其实不结束也啥都输出不出来,浪费点时间而已。

    if(!cnt) cout<<0,exit(0);
    
    冷知识,虽然 return 0; 不能写在逗号后面用于结束程序(无法通过编译),但是 exit(0); 可以

    完整代码

    仅供学习参考使用

    抄袭、复制题解,以达到刷 AC 率/AC 数量或其他目的的行为,在洛谷是严格禁止的。

    洛谷非常重视学术诚信。此类行为将会导致您成为作弊者。 具体细则请查看洛谷社区规则

    #include<bits/stdc++.h>
    using namespace std;
    string tmp,dic[27]={"","one","two","three","four","five",//并不会出现zero 
    "six","seven","eight","nine","ten",//但是这里我为了前20个数下标对应数值把0空着
    "eleven","twelve","thirteen","fourteen","fifteen",
    "sixteen","seventeen","eighteen","nineteen","twenty",
    "a","both","another","first","second","third"};
    int num[6],cnt;
    int main(){
        for(int i=0;i<6;i++){
            cin>>tmp;
            if(!i&&tmp[0]>='A'&&tmp[0]<='Z') tmp[0]+='a'-'A';
            for(int j=1;j<=26;j++){
                if(tmp==dic[j]){
                    if(j<=20){			//在下标1-20匹配即对应1-20 
                        num[cnt++]=j;
                        break;
                    } else {
                        switch(j){
                        case 21: case 23: case 24:	//21、23、24对应1 
                            num[cnt++]=1;break;
                        case 22: case 25:		//22、25对应2 
                            num[cnt++]=2;break;
                        case 26:			//26对应3
                            num[cnt++]=3;break;
                        }
                        break;//switch 语句内的 break 仅能跳出 switch 而对外面的循环没有影响,
                        //因此必须在跳出 switch 后再 break 一次以确保跳出循环(其实继续遍历应该
                        //也没事,不会成功匹配只是浪费点时间)
                    }
                }
            }
        }
        if(!cnt) cout<<0,exit(0);//冷知识,虽然 return 0 不能写在逗号后面用于结束程序但是
    			     // exit(0) 可以
        for(int i=0;i<cnt;i++){
            num[i]=num[i]*num[i];
            num[i]%=100;
        }
        sort(num,num+cnt);
        if(num[0]) cout<<num[0];
        for(int i=1;i<cnt;i++){
            if(num[i]>10){
                cout<<num[i];
            } else {
                cout<<'0'<<num[i];
            }
        }
    }
    

    编辑记录

    修复了最后一个解释不通的地方

    2023-10-28 11:37:00

    修复数学公式渲染

    2021-08-06 18:39:00

    • 1

    信息

    ID
    599
    时间
    1000ms
    内存
    125MiB
    难度
    2
    标签
    递交数
    8
    已通过
    4
    上传者