AcWing 14-B-blank1. 蓝桥杯填空第1题--日期统计
题目
题解
感觉对dfs的板子还不是很熟悉 都想着直接写八重for循环了 写到后面写不下去了
记牢dfs的板子 基础题直接暴搜
本题的关键就是将判断日期是否正确以及是否使用过 和 提取日期 分成两个函数 嵌套
一个易错点就是 当我们判断月份的第二位数据时
并不是pos == 5 && a[x] >= 0 && a[x] <= 2
月份的第二位是0~2 也就是1月~12月 但其实中间还有04 05 09这些月份
应该写成pos == 5 && a[x] >= 0 && a[x] <= 9
#include <bits/stdc++.h>
using namespace std;
int a[110];
bool b[20240010];//用来判断该日期是否重复 要用到2023年所有天数 我们开到2024年
int ans;
//check函数用于判断当前数据是否是合法的日期时间
bool check(int data)
{
if(b[data]) return false; //如果当前日期已经记录过了
int mm = data / 100 % 100; //将data中月份提取出来 巧妙
int dd = data % 100; //提取日期
if (mm < 1 || mm > 12) return false;
if (mm == 1 || mm == 3 || mm == 5 || mm == 7 || mm == 8 || mm == 10 || mm == 12)
{
if (dd < 1 || dd > 31) return false;
}
else if (mm == 2)
{
if (dd < 1 || dd > 28) return false;
}
else
{
if (dd < 1 || dd > 30) return false;
}
b[data] = true; //如果if判断没有return 证明是合法日期 将该日期记录为已搜索过
return true;
}
void dfs(int x, int pos, int data) //x是存数组坐标 也就是搜到第几个数了,pos是当前函数内有几个合法数据了, data存当前数据
{
if (x == 100) return; //已经搜完100个数 返回上层函数
if (pos == 8)
{
if (check(data)) ans ++ ; //如果数据个数已经够了 检查数据是否合法 如果合法就++
return; //返回上一层函数
}
//判断数据能否符合标准进入下一层函数继续搜索
if ((pos == 0 && a[x] == 2)|| (pos == 1 && a[x] == 0) || (pos == 2 && a[x] == 2) || (pos == 3 && a[x] == 3) || (pos == 4 && a[x] >= 0 && a[x] <= 1) || (pos == 5 && a[x] >= 0 && a[x] <= 9) || (pos == 6 && a[x] >= 0 && a[x] <= 3) || (pos == 7 && a[x] >= 0 && a[x] <= 9))
{
//满足上面if集合内的任意一个条件就可以进入下一层继续搜索了
dfs(x + 1, pos + 1, data * 10 + a[x]); //满足条件向下搜 编号+1 合法数据量+1 数据更新
}
//else
dfs(x + 1, pos, data); //如果当前点不满足任何一个要求 就继续向下一个点搜
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
for (int i = 0; i < 100; i ++ ) scanf("%d", &a[i]);
dfs(0, 0, 0);
printf("%d\n", ans);
return 0;
}