日期统计 | 第十五届蓝桥杯省赛C++B组

问题描述

小蓝现在有一个长度为 100100 的数组,数组中的每个元素的值都在 00 到 99 的范围之内。数组中的元素从左至右如下所示:

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 6 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

现在他想要从这个数组中寻找一些满足以下条件的子序列:

  1. 子序列的长度为 8;
  2. 这个子序列可以按照下标顺序组成一个 yyyymmdd 格式的日期,并且要求这个日期是 2023 年中的某一天的日期,例如 20230902,20231223。yyyy 表示年份,mm 表示月份,dd 表示天数,当月份或者天数的长度只有一位时需要一个前导零补充。

请你帮小蓝计算下按上述条件一共能找到多少个不同的 2023 年的日期。对于相同的日期你只需要统计一次即可。

题解:

        使用DFS遍历数组,当遇到要求前四位是2023,第五位可以是0或一,当遇到第六位就判断月份合法性,日期也是相同的方法判断,最后进set去重,看了题解好多方法都只是针对这道题的,这里给个通解。

        垃圾蓝桥云客,题解限字2000还一直提示涉及色情恐怖要素,绷。

代码:

#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#include<iomanip>
#include<queue>
#include<stack>
#include<vector>
#include<unordered_set>
#include<unordered_map>
#include<map>
#include<set>
using namespace std;
typedef long long int ll;
const int INF=1e16;

vector<int> vt;
int days[13]={0,31,28,31,30,31,30,31,31,30,31,30,31};
int cnt=0;
set<string> st;

void dfs(int t,int now,string s){
    if(t>=100){
        return;
    }
    if(now==0 && vt[t]==2){
        dfs(t+1,now,s);
        s+='2';
        dfs(t+1,now+1,s);
    }
    else if(now==1 && vt[t]==0){
        dfs(t+1,now,s);
        s+='0';
        dfs(t+1,now+1,s);
    }
    else if(now==2 && vt[t]==2){
        dfs(t+1,now,s);
        s+='2';
        dfs(t+1,now+1,s);
    }
    else if(now==3 && vt[t]==3){
        dfs(t+1,now,s);
        s+='3';
        dfs(t+1,now+1,s);
    }
    else if(now==4 && (vt[t]==0 || vt[t]==1)){
        dfs(t+1,now,s);
        s+=(char)(vt[t]+48);
        dfs(t+1,now+1,s);
    }
    else if(now==5){
        dfs(t+1,now,s);
        s+=(char)(vt[t]+48);
        string month;
        month=s.substr(4,2);
        //cout << month << "\n";
        int m=10*(month[0]-48)+(month[1]-48);
        if(m>0 && m<13){
            dfs(t+1,now+1,s);
        }
    }
    else if(now==6 && (vt[t]==0 || vt[t]==1 || vt[t]==2 || vt[t]==3)){
        dfs(t+1,now,s);
        s+=(char)(vt[t]+48);
        dfs(t+1,now+1,s);
    }
    else if(now==7){
        dfs(t+1,now,s);
        s+=(char)(vt[t]+48);
        string day;
        day=s.substr(6,2);
        string month;
        month=s.substr(4,2);
        int m=10*(month[0]-48)+(month[1]-48);
        int d=10*(day[0]-48)+(day[1]-48);
        //cout << s << " " << d << " " << m << "\n";
        if(d>0 && d<=days[m]){
            st.insert(s);
        }
    }
    else{
        dfs(t+1,now,s);
    }
}

void solve(){
    for(int i=0;i<100;i++){
        int t;
        cin >> t;
        vt.push_back(t);
    }
    string s="";
    dfs(0,0,s);
    cout << st.size();
}

int main(){
    solve();
}