题目如上,整体思路较为简单,已经有博主写了这个此题,但是代码很多并不是很美观,这里提供自己的代码,其中值得一提的是还可以进一步剪枝(其它博主剪枝多不充分):事实上顺序寻找在数组中发现2023后可以立即停止寻找年份,因为此时已经是最短的包含2023的数组长度,若之后还能够找到其它的2023, 势必重复搜索或者是情况缩小,同理对于月份也是如此处理。
// 日期统计
#include <bits/stdc++.h>
using namespace std;
int data1[] = { 5, 6, 8, 6, 9, 1, 6, 1, 2, 4, 9, 1, 9, 8, 2, 3, 6, 4, 7, 7, 5, 9, 5, 0, 3, 8, 7, 5, 8, 1, 5, 8, 1, 8, 3, 0, 3, 7, 9, 2,
7, 0, 5, 8, 8, 5, 7, 0, 9, 9, 1, 9, 4, 4, 6, 8, 6, 3, 3, 8, 5, 1, 6, 3, 4, 6, 7, 0, 7, 8, 2, 7, 6, 8, 9, 5, 6, 5, 6, 1,
4, 0, 1, 0, 0, 9, 4, 8, 0, 9, 1, 2, 8, 5, 0, 2, 5, 3, 3 };
int n = sizeof(data1) / sizeof(int);
int months[] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
int year[] = {2, 0, 2, 3};
int year_cnt = 0;// 记录年份中多少位数已经找到
int month_begin = 0;// 月份的初始位
int day_begin[13]; // 记录每个月份日期开始位置
set<string> ans; // 答案
void findYear(int goal, int begin) {
for (int i = begin; i < n; i++) {
if (data1[i] == year[year_cnt]) {
year_cnt++;
if(year_cnt == 4){// 找完所有年份
month_begin = i + 1;
return;
}
findYear(year[year_cnt], i + 1);
}
}
}
void findMonth(int goal, int begin, int month_cnt) {
for (int i = begin; i < n; i++) {
if (month_cnt != 1 && data1[i] == 0) {
for (int j = 1; j < 10; j++) {
findMonth(j, i + 1, 1);
}
}
else if (month_cnt != 1 && data1[i] == 1) {
for (int j = 0; j <= 2; j++) {
findMonth(10 + j, i + 1, 1);
}
}else if (goal == data1[i] || month_cnt == 1 && goal - 10 == data1[i]) { // 找到目标数
if (!day_begin[goal])
day_begin[goal] = i + 1;
return;
}
}
}
void dfs(int begin, int month,int day,int cnt) {
if (cnt == 2) {
if (day <= months[month] && day > 0) {// 记录答案
ans.insert(to_string(20230000+month*100+day));
}
return;
}
for (int i = begin; i < n; i++) {
if (cnt == 0 ) {
if (data1[i] <= 3) dfs(i + 1, month, 10 * day + data1[i], 1);
else continue;
}
dfs(i + 1, month, 10 * day + data1[i], cnt+1);
}
}
int main() {
findYear(year[0], 0);
findMonth(-1, month_begin, 0);
for (int i = 1;i <= 12;i++) {
dfs(day_begin[i], i, 0, 0);
}
cout << "共有答案个数:" << ans.size() <<endl;
return 0;
}