1 条题解

  • 0
    @ 2025-8-24 23:03:21

    自动搬运

    查看原文

    来自洛谷,原作者为

    avatar qfy123
    不拿勾7不改签

    搬运于2025-08-24 23:03:21,当前版本为作者最后更新于2024-08-27 20:08:20,作者可能在搬运后再次修改,您可在原文处查看最新版

    自动搬运只会搬运当前题目点赞数最高的题解,您可前往洛谷题解查看更多

    以下是正文


    P11002

    传送门

    Update on 9/129/12

    • 本篇题解的 C++ 部分使用了标准库函数,由于较早版本 C++ 的标准库函数可能存在一些小问题,因此本篇题解无法在 C++98 或 C++14(GCC 9) 的编译选项下拿到满分。

    • Added Python 部分及代码。

    思路

    先考虑“已知输入时间的时间戳为 nownow,如何求在这个时间之前最近一次闹铃响的时间戳”这个问题。不难得出,答案就是 nownowmod60xnow - now \bmod 60x(意思就是用 nownow 减去最后一次闹铃响了之后经过的时间)。

    现在,只要实现时间字符串与时间戳的相互转化即可解决本题。如果直接手写,细节多且实现较麻烦。这时候,我们可以借助编程语言内置的处理时间的库来减小编码难度。

    C++ 部分

    我们可以借助 C++ 内置的 <time.h><sstream> 库来减小编码难度,具体如下:

    1. 将时间字符串转化为时间戳,这部分的代码如下:
    time_t tostamp(string str){
        istringstream ss(str);
    	tm t;
        ss >> get_time(&t, "%Y-%m-%d %H:%M:%S");
        //将字符串表示的时间直接转化成 tm 类型,方便后面操作
        return mktime(&t);//将 tm 类型存储的时间转化为时间戳
    }
    
    1. 将时间戳转化为时间字符串,这部分的代码如下:
    string todate(time_t sta){
        tm* ptm = localtime(&sta);
        //tm *localtime(const time_t *timer):将时间戳转化为tm类型。
        ostringstream oss;
        oss << put_time(ptm,"%Y-%m-%d %H:%M:%S");
        return oss.str();
        //上面三行:将 tm 类型存储的时间转化为字符串
    }
    

    关于以上出现的标准库函数与类型,如有不知道的,请自行 bdfs。

    代码

    #include<bits/stdc++.h>
    using namespace std;
    time_t tostamp(string str){
        istringstream ss(str);
    	tm t;
        ss >> get_time(&t, "%Y-%m-%d %H:%M:%S");
        //将字符串表示的时间直接转化成 tm 类型,方便后面操作
        return mktime(&t);//将 tm 类型存储的时间转化为时间戳
    }
    string todate(time_t sta){
        tm* ptm = localtime(&sta);
        //localtime():将时间戳转化为tm类型的本地时间
        ostringstream oss;
        oss << put_time(ptm,"%Y-%m-%d %H:%M:%S");
        return oss.str();
        //上面三行:将 tm 类型存储的时间转化为字符串
    }
    string s1,s2;
    int x,T;
    int main() {
    	ios::sync_with_stdio(false);
    	cin.tie(0);cout.tie(0);
    	cin >> T;
    	while(T--){
    		cin >> s1 >> s2 >> x; //读入的时间中间有空格,因此要用两个字符串先存着
        	x *= 60; // 时间戳是以秒为单位,而题目给的x是以分钟为单位的,所以要进行转化
        	string str = s1 + ' ' + s2;//还原为完整时间
    		time_t sta = tostamp(str);//将输入时间转化为时间戳
    		time_t ans = sta - sta % x;//求出答案时间戳
    		string res = todate(ans);//将答案时间戳转化为日期格式
    		cout << res << '\n';
    	}
        return 0;
    }
    

    Python 部分

    对于 Python 而言,我们可以使用 datetime 库来解决这个问题。由于前文以及代码里的注释已经讲的足够清晰了,因此不再赘述。

    代码

    from datetime import *
    
    def solve(delta, str):
        # 将传入的字符串转换为datetime类型
        tm = datetime.strptime(str, '%Y-%m-%d %H:%M:%S')
        # 起始时间设为 1970-01-01 00:00:00
        st = datetime(1970, 1, 1)
        # 计算现在的时间
        now = tm - st
        # 算出时间戳
        tots = now.total_seconds() 
        # 用之前所述的公式计算答案时间戳
        anss = tots - tots % delta
        # 以下两行:将答案时间戳还原并返回
        anst = st + timedelta(seconds=anss)
        return anst.strftime('%Y-%m-%d %H:%M:%S')
    
    t = int(input())
    for i in range(t):
        ymd, hms, delta = input().split()
        delta = int(delta)
        # 还原成完整时间并传入solve函数
        ans = solve(delta * 60, ymd + ' ' + hms)
        print(ans)
    
    • 1

    信息

    ID
    10697
    时间
    1000ms
    内存
    512MiB
    难度
    2
    标签
    递交数
    0
    已通过
    0
    上传者