Round799-Div4 D题题解

Round799-Div4 D题题解

  • 题意:

    • 给出当前时间,例如12:21,再给一个数,输出所有当前时间加上数后成为互逆时间(13:31,10:01,00:00)的可能性结果。时间格式为字符串,内容样式如上。

    • Input:
      6
      03:12 360
      00:00 1
      13:22 2
      15:15 10
      11:11 1440
      22:30 27
      
      Output:
      1
      16
      10
      0
      1
      1
      
  • 分析

    • 首先我想到类似打表的方式:将所有可以互逆的时间存储再一个数组中。考虑到输入的数X格式是分钟,所以应该将可以互逆的时间全部转换成分钟,同时,想要依次访问的话,最好是用一个set<int> revTime,这样的话,我们可以在后面使用:

      for(auto &it : revTime)
      

      来用it依次访问可行的时间。

    • 还有一个问题,如何判断一个时间是否为互逆时间呢?

      • 我们可以将小时部分和分钟部分分割开,利用数字的性质,对10做除法和对10取余,如果结果相等,就证明前后互逆。

      • if(hour % 10 == minute / 10 && hour / 10 == minute % 10)
        	ans++;
        
    • 还有一个问题,输入的时间格式为字符串,如何将它转换为真实的数字呢?

      • atoi()函数
        • 这个函数可以将字符串转换成任意想要的数字进制,如果啥都不填,默认十进制。
      • 一个很好的思路是,采用两个字符串,分别用来装输入的小时与分钟,转换后再加起来。
  • 实现

    • 首先想到,将所有的逆序时间以分钟的方式存储起来,存储在set中:

      set<int> revTime;
      for(int i = 0; i < 1440; i++) {
          int X = i % 60, Y = i / 60;		//X是分钟,Y是小时
          if(X % 10 == Y / 10 && X / 10 == Y % 10)
              revTime.insert(i);
      }
      
    • 其次讨论如何存储输入

      • 输入的时间格式为字符串,如何将它转换成数字然后进行运算呢?答案是用atoi函数转换成数字

      • 考虑到时间字符串中间有个:符号,同时为了将小时和分钟分开运算,我们采用两个字符串进行存储:

        string A = "", B = "";
        //输入时间为S
        A += S[0]; A += S[1]; B += S[3]; B += S[4];
        
        //之后用一个int变量存储当前时间
        int curT = stoi(A) * 60 + stoi(B);
        
        • 首先,我们好好分析一下上面过程和我学到的东西:

          string A = "";
          
        • 这条语句重点在于,声明并且初始化了一个元素个数为一,内容为空的字符串。为什么要这样做呢?

          • 1.方便后面对于原串的提取

            2.我们只需要用到A的一个元素,所以直接声明一个空的元素,然后直接将内容加入

            3.原串中字符单个排列,格式复杂,得一一提取

      • 搞定了输入问题,我们得到了curT,即输入的分钟数。如何判断它是否为互逆串呢?

      • 首先思考:给出每次要数的分钟数,实际上就是将一共的24个小时;1440分钟用给出的分钟数分解。所以,输入的时间对计数分钟X取余应当和满足条件的分钟数对计数分钟X取余相等

        for(auto &it : S) {
            if(it % X == curT % X)
                ans++;
        }
        
  • 讨论完毕,上代码:

    #include <bits/stdc++.h>
    using namespace std;
    
    set<int> revTime;   //存储所有可逆时间
    
    int main()
    {
        ios::sync_with_stdio(false); cin.tie(0);
        for(int i = 0; i < 1440; i++) {     //24小时是一共拥有的时间
            int X = i % 60, Y = i / 60;     //X分钟,Y小时
            if(X % 10 == Y / 10 && X / 10 == Y % 10)
                revTime.insert(i);
        }
        int N;
        cin >> N;
        while (N--) {
            string S; cin >> S;
            int X; cin >> X;
    
            /* 这里写的非常好 */
            X = __gcd(X,1440);
            string A = "", B = "";
            A += S[0]; A += S[1];
            B += S[3]; B += S[4];
            int curT = stoi(A) * 60 + stoi(B);
            int ans = 0;
            for(auto &it : revTime) {
                if(it % X == curT % X)      //找相同因素:可逆时间与当前时间(符合条件的)对公因数除的结果相同
                    ans++;
            }
            cout << ans << endl;
        }
        return 0;
    }
    
posted @ 2022-06-16 12:06  は?無理です!  阅读(37)  评论(0)    收藏  举报