EOJ Monthly 2020.1 A.回文时间

在这里插入图片描述
在这里插入图片描述

第一种解法 找规律

1.思路

在这里插入图片描述

  • 如图是一一对称关系 要注意的是这里把年份分成了两半
  • ”是最中间的,要想对称 只能是 11 或 22 这 2种情况
int ri[2]={11,22};
  • 接着分析“月–时”这一对,对于月份要满足1 ~ 12,时要满足0 ~ 23
    所以只有以下5种情况 :
    月 时
    01–10
    02–20
    11–11
    12–21
    13–31
int yue[5]={1,2,10,11,12};
  • 接着分析“后年–分”这一对,后年满足0 ~ 99,分满足0~59;从范围可知,对于所有的分均有相应的后年与之对应,所以共有60种情况

    这里只列举后年的数值,分的数值与其对称

int hyear[60]={0,1,2,3,4,5,10,11,12,13,14,15,20,21,22,23,24,25,30,31,32,33,34,35,40,41,42,43,44,45,50,51,52,53,54,55,60,61,62,63,64,65,70,71,72,73,74,75,80,81,82,83,84,85,90,91,92,93,94,95};
  • 最后是“前年–秒”这一对,前年范围是20 ~ 90,秒范围是0~59,共有48种情况
int qyear[48]={20,21,22,23,24,25,30,31,32,33,34,35,40,41,42,43,44,45,50,51,52,53,54,55,60,61,62,63,64,65,70,71,72,73,74,75,80,81,82,83,84,85,90,91,92,93,94,95};

那么接下来,就是捋清楚排序问题
我们通常会改变秒,再改变时。。。

但因为是前后对称的 只要改变小时,分,秒,那么月,后年,前年都会相应变化!!!,所以改变秒,实际上也同时改变了年份。顺序就不对了。

所以只要看前半部分就好,变化顺序依次是
日->月->后年->前年.

2.AC代码

#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <iostream>
#include <algorithm>
using namespace std;
int qyear[48]={20,21,22,23,24,25,30,31,32,33,34,35,40,41,42,43,44,45,50,51,52,53,54,55,60,61,62,63,64,65,70,71,72,73,74,75,80,81,82,83,84,85,90,91,92,93,94,95};
int hyear[60]={0,1,2,3,4,5,10,11,12,13,14,15,20,21,22,23,24,25,30,31,32,33,34,35,40,41,42,43,44,45,50,51,52,53,54,55,60,61,62,63,64,65,70,71,72,73,74,75,80,81,82,83,84,85,90,91,92,93,94,95};
int yue[5]={1,2,10,11,12};
int ri[2]={11,22};

int main()
{
    int a,b,c,d,k,qy,hy,y,r,s,f,m;
    cin>>k;
    
        k=k+122;///初始时间为2000 01 11 10 00 02(各数组的第一个数),那么题目给的开始时间是第122个。
        a=(k-1)/600;///600是由2*5*60得来的,即一个前年(qyear)共对应600种情况,第六百个还属于qyear【0】,(k-1)是为了避免将它划分到qyear【1】中。
        qy=qyear[a];
        k=k-a*600;
    //cout<<a<<endl;
        if(k==0){m=qy/10+(qy%10)*10;printf("%02d6012222106%02d",qy,m);return 0;}///如果减完之后,k=0,那么他就是这一组的最后一种情况,如输出。
        b=(k-1)/10;///10由2(日)*5(月)得来,一个后年共对应10种情况。
        hy=hyear[b];
        k=k-b*10;
    //cout<<b<<endl;
        if(k==0){m=qy/10+(qy%10)*10;f=hy/10+(hy%10)*10;printf("%02d%02d122221%02d%02d",qy,hy,f,m);return 0;}
        c=(k-1)/2;
    //cout<<c<<endl;
        y=yue[c];
        k=k-c*2;
        m=qy/10+(qy%10)*10;f=hy/10+(hy%10)*10;s=y/10+(y%10)*10;
        if(k==2){printf("%02d%02d%02d22%02d%02d%02d",qy,hy,y,s,f,m);return 0;}
        ///%02d  会自动补零
        else{printf("%02d%02d%02d11%02d%02d%02d",qy,hy,y,s,f,m);return 0;}
}

第二种解法 for循环,结构体

1.思路

前期分析与解法一相同

  • 结构体存各个数据
struct ans
{
    int year;
    int month;
    int date;
    int hour;
    int minute;
    int second;
}f[30000];
  • for循环 从2020年一直循环到9999年
    得到分和秒的数值,判断是是否符合条件,即属于0~59
  • 如果符合条件,那么这一年就会有10种情况(2种date*5种month)
  • 然后存入结构体数组中

2.AC代码


#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cmath>
#include<cstring>
using namespace std;
int month[6] = {0,1,2,10,11,12};
int date[3] = {0,11,22};
struct ans
{
    int year;
    int month;
    int date;
    int hour;
    int minute;
    int second;
}f[30000];


int main()
{
    int k;
    cin >> k;
    int t=1;
    for(int i = 2020; i <= 9999; i ++)
    {
        int a = i;
        int b = a % 100;
        int minute = (b%10) * 10 + (b/10);
        if(minute >= 0 && minute <= 59)
        {
            int c = a / 100;
            int second = (c%10) * 10 + (c/10);
            if(second >= 0 && second <= 59)
            {
                for(int p=1;p<=5;p++)///月
                {
                    for(int w=1;w<=2;w++)///日
                    {
                        f[t].year=a;
                        f[t].month=month[p];
                        f[t].date=date[w];
                        f[t].hour=f[t].month/10+(f[t].month%10)*10;
                        f[t].minute=minute;
                        f[t].second=second;
                        t++;
                    }
                }
            }
        }
    }
    int m=k+2;///题目给的时间,是数组中的第二个
    printf("%d%02d%02d%02d%02d%02d",f[m].year,f[m].month,f[m].date,f[m].hour,f[m].minute,f[m].second);
return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值