蓝桥杯省赛题:特殊时间

文章描述了一道蓝桥杯省赛的编程填空题,题目要求找出所有年月日时分由3个相同数字和1个不同数字组成的四位数,例如2022年2月22日22:20。解答者采用组合方法,遍历数字组合并检查合法性,最终得到212个符合条件的时间。
摘要由CSDN通过智能技术生成

本题为2022年蓝桥杯省赛的填空题。

问题描述

本题为填空题,只需要算出结果后,在代码中使用输出语句将所填结果输出即可。

2022 年 2 月 22 日 22: 20 是一个很有意义的时间, 年份为 2022 , 由 3 个 2 和 1 个 0 组成, 如果将月和日写成 4 位, 为 0222 , 也是由 3 个 2 和 1 个 0 组 成, 如果将时间中的时和分写成 4 位, 还是由 3 个 2 和 1 个 0 组成。

小蓝对这样的时间很感兴趣, 他还找到了其它类似的例子, 比如 111 年 10 月 11 日 01: 11,2202 年 2 月 22 日 22: 02 等等。

请问, 总共有多少个时间是这种年份写成 4 位、月日写成 4 位、时间写成 4 位后由 3 个一种数字和 1 个另一种数字组成。注意 1111 年 11 月 11 日 11: 11 不算,因为它里面没有两种数字。

运行限制

  • 最大运行时间:1s
  • 最大运行内存: 512M

 

题解: 本题中不需考虑平年闰年的问题,因为平年闰年的区别主要在于是否有2月29日这一天,显然有关月日的四位数字“0229”不满足3个数和1个另一个数组成的情况,所以无论平年还是闰年没必要枚举2月29日这一天。接下来则是用组合的角度思考,对于年份,月日,时分,每一个4位数字,显然有4种不同的组合方式。比如对于由数字2和数字0组成的4位数,包括0222、2022、2202、2220这4种不同的组合方式。因此可以先从0~9这10个数中依次挑选两个不同的数进行组合,显然每次都有4种不同的组合方式。接下来再依次枚举这4种组合方式组成的4位数,判断合法性即可。

答案:212

(纯C语言)参考程序代码:

#include <stdio.h>
int monthday[13]= {0,31,28,31,30,31,30,31,31,30,31,30,31};
char c[4][4];   //定义二维字符数组,存储由两个不同的数组成的四位数的所有组合方式 
int main() {
  int ans=0;
  for(int d1=0; d1<10; d1++) {
    for(int d2=0; d2<10; d2++) {
      if(d1==d2) continue;    //从0~9分别筛选出两个不同的数d1,d2,使其组成一个四位数
      for(int i=0; i<4; i++) { //组成的四位数中d1有1个,而d2有3个,显然一共有4种不同的组合方式
        for(int j=0; j<4; j++) {
          c[i][j]='0'+d2;
        }
        c[i][i]='0'+d1;
      }
      for(int i=0; i<4; i++) { //枚举4种不同的组合方式,给年份赋值
        int year;
        sscanf(c[i],"%d",&year);   //字符数组c[i]转换为十进制整型数,并赋值给year
        for(int j=0; j<4; j++) { //枚举4种不同的组合方式,给月日赋值
          int month,day;
          sscanf(c[j],"%2d%2d",&month,&day);  //字符数组c[j]转换为十进制整型数,并从左到右(数位宽度为2)分别赋值给month,day
          if(month<1 || month>12) continue; //排除月日不合法的情况
          if(day<1 || day>monthday[month]) continue;
          for(int k=0; k<4; k++) { //枚举4种不同的组合方式,给时分赋值
            int hour,minute;
            sscanf(c[k],"%2d%2d",&hour,&minute);  //字符数组c[k]转换为十进制整型数,并从左到右(数位宽度为2)分别赋值给hour,minute
            if(hour<0 || hour>23) continue; //排除时分不合法的情况
            if(minute<0 || minute>59) continue;
            ans++;             //满足所有合法条件后,方案数加1
          }
        }
      }
    }
  }
  printf("%d\n",ans);   //打印输出:212
  return 0;
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值