试题 A: 日期统计
本题总分: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 年的日期。
对于相同的日期你只需要统计一次即可。
【答案提交】
这是一道结果填空的题,你只需要算出结果后提交即可。本题的结果为一
个整数,在提交答案时只填写这个整数,填写多余的内容将无法得分
解题思路:
这题不少可能人没理解子序列的定义,子序列即原数组按下标递增规律所挑出的子集,同时这个递增可以是没有规则的(他可以从1跳到10再到30的位置,但就是不能从30回到1)
在确定年份2023固定之后,我们可以对原来的100大小的数组进行化简,得到一个新的数组。
然后将月份日期拆分成4个int型,a1是月份的第一个数字,a2是月份第二个数字。。。
同理将4个int型对应4个循环嵌套即可保证子序列的规则。
最后只需要判断4个数最后是否符合日期规则,若符合则放入set数组即可。
代码部分:
1 #include<iostream> 2 #include<set> 3 #include<string> 4 using namespace std; 5 string str1= "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"; 6 string s; 7 int get_month[13]={0,31,28,31,30,31,30,31,31,30,31,30,31}; 8 set<int> date; 9 bool date_judge(int a1,int a2,int a3,int a4) 10 { 11 int month=a1*10+a2; 12 int day=a3*10+a4; 13 if(get_month[month]<=day) 14 return false; 15 return false; 16 } 17 int main(){ 18 for(int c:str1){ 19 if(c !=' ') 20 { 21 s+=c; 22 } 23 } 24 for(int i=0;i<s.length();i++) 25 { 26 if(s[i]!='1'&&s[i]!='0') 27 continue; 28 for(int j=i+1;j<s.length();j++) 29 { 30 if(s[i]=='1'&&s[j]>'2') 31 continue; 32 if(s[i]=='0'&&s[j]=='0') 33 continue; 34 for(int k=j+1;k<s.length();k++) 35 { 36 if(s[k]>'3') 37 continue; 38 for(int l=k+1;l<s.length();l++) 39 { 40 if(s[k]=='3'&&s[l]>'1') 41 continue; 42 if(s[k]=='0'&&s[l]=='0') 43 continue; 44 int a1=(s[i]-'0'),a2=(s[j]-'0'),a3=(s[k]-'0'),a4=(s[l]-'0'); 45 if (date_judge(a1,a2,a3,a4)); 46 { 47 a1*=1000; 48 a2*=100; 49 a3*=10; 50 int Date=a1+a2+a3+a4; 51 date.insert(Date); 52 } 53 } 54 } 55 } 56 } 57 cout<<date.size()<<endl; 58 }