试题 A: 日期统计(蓝桥杯省赛B组)

本题总分:5 分
 
【问题描述】
小蓝现在有一个长度为 100 的数组,数组中的每个元素的值都在 0 到 9 的范围之内。数组中的元素从左至右如下所示:
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 年的日期。对于相同的日期你只需要统计一次即可。
 
【答案提交】
这是一道结果填空的题,你只需要算出结果后提交即可。本题的结果为一个整数,在提交答案时只填写这个整数,填写多余的内容将无法得分。

/*
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
*/
/*
答案:235
*/
/*
按照格式mmdd 属于2023年中的一个日期
子序列保持在原来序列中的相对位置 

普通年份能被 4 整除但不能被 100 整除的为闰年
世纪年份能被 400 整除的是闰年
*/

#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;

vector<int> num(100);
//存储原来序列 
int ans=0;
//存储结果
bool visit[20240000];
//bool vis[20240000];
//记录被访问过的日期
bool check(int data){

    if(visit[data])return false;
    visit[data]=true;
    //处理之前相同的日期    
    int year=data/10000;
    //提取日期中的年份 
    int month=data/100%100;
    //提取日期中的月份 
    int day=data%100;
    //提取日期中的天数
   
    if(year==2023&&1<=month&&month<=12){
        //2023是平年,2月份只有28天
        if(month==2){
            if(1<=day&&day<=28)
             return true;
        }
        //大月份
        else if(month==1||month==3||month==5||month==7||month==8||month==10||month==12){
                if(1<=day&&day<=31)
                return true;}
            //小月份 
        else {
        if(1<=day&&day<=30)
            return true;
        }
    }
    //不合法日期 
    return false;
}

void dfs(int index,int pos,int data) {
    //index当前处理到原序列的第index位
    //pos当前处理到子序列的第pos位
    //data计算每次搜索得到最终日期 
    if(index==100)return;
    //所有数据被处理完了
    if(pos==9){
        //static int i=1;
        //cout<<"到这里"<<i++<<"次"<<endl;
        if(check(data))++ans;
        //检查日期是不是合法 
        return;
    }
    
    if((pos==1&&num[index]==2)||
       (pos==2&&num[index]==0)||
       (pos==3&&num[index]==2)||
       (pos==4&&num[index]==3)||
    (pos==5&&0<=num[index]&&num[index]<=1)||
    (pos==6&&0<=num[index]&&num[index]<=9)||
    (pos==7&&0<=num[index]&&num[index]<=3)||
    (pos==8&&0<=num[index]&&num[index]<=9))
    dfs(index+1,pos+1,data*10+num[index]);
    
    //回溯
    dfs(index+1,pos,data);
    
}
int main(){
    ios::sync_with_stdio(0);cin.tie(0);
    //必须在第一次使用iostream或者stdio之前调用
    //关闭iostream和stdio同步,增快输出速度,处理大量输入输出 
    for(int i=0;i<100;i++)
    cin>>num[i];
    //存储数据
    dfs(0,1,0);
    cout<<ans<<endl;
    return 0;
}


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值