本题为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;
}