尝试再做一次,我记得还是有点难,我会尽量多写一点解析,尽量让基础比较弱的友友也能看懂,希望能给你带来帮助
目录
1. 日期统计
题目描述
小蓝现在有一个长度为 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 年的日期。
对于相同的日期你只需要统计一次即可。
解题思路
这道题在赛场上大家可能和我一样,脑子里面第一想法就是循环遍历,反正就8次,我也是这么做的,后面我的老师给我介绍了另一种解法,我都写一下
方法一
直接简单粗暴地循环,唯一需要注意的是记得筛出重复的日期,我用的set(不太清楚set用法的友友需要自己查一下哦),自动帮我去重,我将每次符合条件的日期(一个八位数的数字)insert到set容器中,后面循环结束后,set的长度就是满足要求的日期的个数(具体代码在下面)
方法二:
这是老师赛后告诉我的,我看见网上也有很多这样写的。不需要循环原本的数组,而是循环遍历2023年的每一天,看看这一天年-月-日这八个数字是否在原数据中也顺序出现,这种解法就不要考虑有相同日期的情况(我文字描述不太清楚,可以直接看下面的代码,看了就知道)
具体代码
方法一代码
这个代码看起来很长,其实很简单(思路见上),就是八重循环,但是需要仔细再仔细,代码里面我也有写注释,可以看看,不难
// 长度为8 2023 01 24
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 3e5+ 24 , M = 1e9 + 24 , n = 100;
// 原数据
int m[100] = {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};
// 存每月有多少天
int D[] = {0 , 31 , 28 , 31 , 30 , 31, 30 , 31 , 31 , 30 , 31 , 30 , 31};
set<int> s; //用set记录满足要求的日期(数字),自动会去重,这样set中数字的个数就是答案
int main()
{
int a , b , c , d , e , f , j , h , day , month , date;
// 1、确保前面4个数字是 2023 abcd
for(a = 0 ; a < n ; a ++)
{
if(m[a] == 2) // 2
{
for(b = a+1 ; b < n ; b ++)
{
if(m[b] == 0) // 0
{
for(c = b+1 ; c < n ; c ++)
{
if(m[c] == 2) // 2
{
for(d = c+1 ; d < n ; d ++)
{
if(m[d] == 3) // 3
{
// 2、保证后面四位 月-日符合逻辑 efjh
for(e = d+1 ; e < n ; e ++)
{
for(f = e+1 ; f < n ; f ++)
{
// 几月?? 满足month在1-12
month = m[e]*10 + m[f];
if(month >= 1 && month <= 12)
{
for(j = f+1 ; j < n ; j ++)
{
for(h = j+1 ; h < n ; h ++)
{
// 几日?? 满足day在1-D[month]对应月的日期内
day = m[j]*10 + m[h];
if(day >= 1 && day <= D[month])
{
date = 2023*10000 + month*100 + day;
s.insert(date);
}
}
}
}
}
}
}
}
}
}
}
}
}
}
cout << s.size();
return 0 ;
}
方法二代码
代码里面的注释写的比较详细可以看看
// 方法二
// 长度为8 2023 01 24
#include <iostream>
#include <algorithm>
#include <cmath>
using namespace std;
typedef long long ll;
const int N = 3e5+ 24 , M = 1e9 + 24 , n = 100;
// 原数据
int m[100] = {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};
// 存每月有多少天
int D[] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
int main()
{
int month, day, i, j, ans = 0 ;
// 遍历2023年的12个月
for(month = 1 ; month <= 12 ; month ++)
{
// 遍历每一天
for(day = 1 ; day <= D[month] ; day ++)
{
string str = "2023";
if(month < 10) str += "0"; //月份只有一位数需要0填充
//