本题为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
答案1:
#include<iostream>
using namespace std;
int day_per_month[] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
//闰年对该题的结果没有影响,因此不考虑闰年二月的日期
//此外,年份在该题中是没有限制的,因此不探讨年份的合法性
//在题中年份、月日、时间均以整体的形式存在
bool check_D(int D){//检查日期D是否合法
int month = D / 100;
int day = D % 100;
if(month < 1 || month > 12)return false;
if(day < 1 || day > day_per_month[month])return false;
return true;
}
bool check_H(int H){//检查时刻H是否合法
int h = H / 100;
int m = H % 100;
if(h < 0 || h > 23)return false;
if(m < 0 || m > 59)return false;
return true;
}
int main(){
int ans = 0;
for(int a = 0; a <= 9; a++){ //枚举第一个数字
for(int b = 0; b <= 9; b++)//枚举第二个数字
if(a != b) {
int N_Y = 4, N_D = 0, N_H = 0; //合法数量,由于年份没有限制,枚举两个数字后,必定有4个合法年份
int A[4] = {a, a, a, a};
//枚举四种情况aaab、aaba、abaa、baaa
for(int i = 0; i < 4; i++) {
A[i] = b;
int number = 0;
for(int j = 0; j < 4; j++)
number = number * 10 + A[j];
N_D += check_D(number);
N_H += check_H(number);//这里有个知识点,即bool(true)返回的值是1,bool(false)返回的值时0
A[i] = a;//给它归a,换一个枚举情况
}
ans += N_Y * N_D * N_H;//计算笛卡尔集,即合法个数
}
}
cout<<ans<<endl;
return 0;
}
答案2:
#include <iostream>
using namespace std;
int main()
{
// 请在此输入您的代码
//年:**** A行
//月**日** B行
//时**分** C行
//年份无论闰年平年没有影响。从月份入手,分两种情况:
// 零开头:01 02两种 所以第二行是0111或0222 共有2*4*4=32种
// 一开头:10 11 12
// 10: 1000(×) 1011(√) 4*1*4=16种
// 11: 11*1—— 1101(√) 1111(×)1121(√)1131(×)1141..无 2种 2*4*4=32种
// 111*—— 1110(√) 1111(×)1112(√) 4*2*4=32种
// 1113(3种)1114(3种)1115(3种)4*3*3=36种
// 1116、1117、1118、 1119 (2种) 4*4*2=32种
// 12: 1211 (√) 1222(√) 4*2*4=32种
// 总数为:4*4*(2+1+2+2+2+2)+4*3*3=212;
cout<<4*4*(2+1+2+2+2+2)+4*3*3<<endl;
return 0;
}