EOJ #3737. 回文时间

题目描述:

Cuber QQ 很惊奇地发现 2020 年 1 月 22 日的 10:02:02 构成的字符串竟然是一个回文串。(构成的字符串是 20200122100202 ),这下又有充足的理由约女神吃饭了。可是这之后,女神开始为难 Cuber QQ 了。她现在只允许 Cuber QQ 在回文时间约她吃饭。

回文时间指的是,年份(四位数字构成)+月份(两位数字构成)+日期(两位数字构成)+小时(两位数字构成)+分钟(两位数字构成)+秒(两位数字构成)所形成的字符串是一个回文字符串。其中时间的表示形式是 24 小时制,例如下午 01:02 表示为 13:02 。

于是 Cuber QQ 开始期待之后的约会了。他现在想知道 2020 年 1 月 22 日的 10:02:02 之后第 k 个回文时间是多少(特别地,之后第 0 个回文时间就是 20200122100202 )。

保证他们约会的时间不可能晚于 9999 年 12 月 31 日的 23:59:59 。

输入格式

输入数据包含一行一个整数 k ,表示要求的是之后的第 k 个回文时间。

保证对于给定的输入,输出的答案不会大于 99991231235959 ,即晚于 9999 年 12 月 31 日的 23:59:59 。

输出格式:

输出一行一个字符串表示答案。

样例:

Input
28677
Output
95951211215959

思路分析:

本题的解题方法挺多的,可以考虑将中间10位变化不多(10次)的写在数组里,只对年份进行判断,也可以选择直接计算出。这里选择用第二种方法来描述,可以帮助读者理解。

 

首先我们可以看出,题目要求给出回文时间会受到月份、日期、时间三种格式的相互干扰,例如月份要求在01、02...12之间选择,日期要求在01、02...31之间选择。在观察之后会发现,月份会与时相互作用,因此可选的月份有01、02、10、11、12,相应的时为10、20、01、11、21。同样的年份前两位与后两位分别会与分秒相互作用,这里有60种变化,00-05,10-15,...90-95。

因此开辟时间数组t[8],t[0]t[1]表示年份前两位有60种变化,t[2]t[3]表示年份后两位有60种变化,t[4]t[5]表示月份有5种变化,t[6]与t[7]相等表示日期,只有0,1两种可选。我们选择0000011(1100000)为起点,这与题目要求的2020012(2100202)之间相差了7321(12*60*5*2+12*5*2+1),因此在输入n之后加上这个距离即可。

代码:

#include <bits/stdc++.h>
using namespace std;

int main() {
    int t[8] = {0};
    int n, a, b, c, d;
    cin >> n;
    n += 7321;
    a = n / 600;
    b = n % 600 / 10;
    c = n % 10 / 2;
    d = n % 2;
    t[0] = a / 6;
    t[1] = a % 6;
    t[2] = b / 6;
    t[3] = b % 6;
    t[4] = (c > 1) ? 1 : 0;
    t[5] = (c > 1) ? c - 2 : c + 1;
    t[6] = d + 1;
    for(int i = 0; i < 7; i++) {
        cout << t[i];
    }
    for(int i = 6; i >= 0; i--) {
        cout << t[i];
    }
    cout << endl;

    return 0;
}

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值