PTA |1014 福尔摩斯的约会 日期模拟类问题

98 阅读3分钟

PTA |1014 福尔摩斯的约会

视频解析

首先读入四行字符串分为两对来处理

前两行来寻找week和小时

后两行来找mintues。

week

这道题利用字母下标映射来建立映射表,找到字母之后在映射表查找对应元素,就可以把week找到了。

hour

小时用了扑克牌那样的规则:数字+字母

本题的规则是A B C D E F G H I J K L M N 0 1 2 3 4 5 6 7 8 9,这代表24h

如果我们找到了字母,我们利用ASCII把字母转变为数字再加上缺失的数字0~9,即再加上10,就是正是的hour

如果找到了数字,直接输出数字就是hour

minutes

获取minute比较简单,因为我们是用string输入字符串的,在遍历后两行的时候找到相同字母之后 按照题目规则"现在第 几个位置(从 0 开始计数)上,代表第 几分钟" 输出对应下标即是mintues; image.png

code

#include<iostream>
#include<string>
#include<cctype>
using namespace std;
int main()
{
    string weeks[7]={"MON","TUE","WED","THU","FRI","SAT","SUN"};
    //输入四行字符串,前面两行处理week,hour问题。后两行处理minuteshour问题
    string a,b,c,d;
    cin>>a>>b>>c>>d;

    int i=0;
    char temp[2];
    while(i<a.length()&&i<b.length())
    {
        //如果都是大写字母并且相同就映射 ps:说错了,虽然是要大写字母但是仍然有范围,因为映射的是周一到周日,只有七天,所以范围应该是A~G
        if(a[i]==b[i]&&a[i]>='A'&&a[i]<='G')
        {
            //可以先保存起来,输出的时候再映射输出即可
            temp[0]=a[i];
            break;
        }  
        i++;
    }
    i+=1;//跳到下一个字母位置,继续向后遍历
    
    while(i<a.length()&&i<b.length())
    {
        //如果a[i]是数字 或者 是字母(要满足只能是A~N这14个字母),那就合法
        if(a[i]==b[i]&&(a[i]>='A'&&a[i]<='N'||isdigit(a[i])))/这里注意a[i]==b[j]和([i]是字/字母),整体是一个并列关系,注意括号结合性,否则容易报错
        {
            //找到时间了。保存一下
           temp[1]=a[i];
              break;
        }
        i++;//迭代
    }

    //minutes
    int index=0;
    int minutes;
    while(index<c.length()&&index<d.length())
    {
      //如果a[j]和a[j+1]都字母并且值相同,那就合法
        if(c[index]==d[index]&&isalpha(c[index]))
        {
            //找到了就保存一下;
            minutes=index;  //下标就是minutes
            break;
        }
        index++;
    }


    //输出部分
    //依次输出  week hour minutes

    cout<<weeks[temp[0]-'A']<<" ";   //映射week
    
    //小时 E-A=4, 4再加上缺失的0~9 十个数字,就是真实的hour:N这14个字母
    // int H=hours-'A'+10;
    //上面写错了,映射小时候之前我们要先判断一下我们找到的hour是数字还是字母,是数字就不用转化了,是字母才需要转换:
    int hour=isdigit(temp[1])?temp[1]-'0':temp[1]-'A'+10;
   
    printf("%02d:%02d",hour, minutes);
    return 0;
}

二刷

解析:14_哔哩哔哩_bilibili

#include<bits/stdc++.h>
using namespace std;
string week[8]={"MON","TUE","WED","THU","FRI","SAT","SUN"};
int main()
{
    string a,b,c,d;cin>>a>>b>>c>>d;

   bool flag=false;
    for(int i=0;i<a.length()&&i<b.length();i++)
    { 
       if(a[i]==b[i]&&a[i]>='A'&&a[i]<='G'&&!flag)
       {
          cout<<week[a[i]-'A']<<" ";
           flag=true;
           continue;
       }
       if(flag)
       {
           if(a[i]==b[i]&&a[i]>='0'&&a[i]<='9')
           {
               printf("%02d",a[i]-'0');
               break;
           }
           if(a[i]==b[i]&&a[i]>='A'&&a[i]<='N')
           {
               printf("%02d",a[i]-'A'+10);
               break;
           }
       }
    }
    for(int i=0;i<c.length()&&i<d.length();i++)
    {
        if(c[i]==d[i]&&isalpha(c[i]))
            printf(":%02d",i);
    }
    return 0;
}

image.png

坑点

一。前两行字符串第一对大写的英文字母必须是A-G而不是A-Z,因为一星期有7天,正好对应A-N;

二。及时break。

前两行字符串找到第二个相同字母输出之后如果没有及时break就会有一个点过不去:

image.png image.png