AcWing 14-B-blank1. 蓝桥杯填空第1题--日期统计

题目

蓝桥杯大赛历届真题-C-C-大学-B-组-蓝桥云课.png


题解

感觉对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;
}
posted @ 2024-04-16 17:01  MsEEi  阅读(9)  评论(0)    收藏  举报