当前位置: 首页 > article >正文

【蓝桥杯】每日练习 Day13

前言

今天做了不少题,但是感觉都太水了,深思熟虑之下主播决定拿出两道相对不那么水的题来说一下(其实还是很水)。

两道问题,一道是日期问题(模拟),一道是区间合并问题。


日期差值


分析

这样的问题其实就是模拟,但是我们可以发现在模拟的过程中需要处理年份,月份,天数,进位等情况,如果都去用if - else嵌套去写的话那未免太不优雅了。

所以主播带了一种可以优雅的处理这种问题的方法。

这种方法是开始先将日期转化成从0001-01-01到此日期经过了多少天,随后两个数字相减就可以了,怎么样,是不是很简单。

那么我们如何来计算有多少天呢,先来试着按照每一天来枚举,可以发现总共枚举的话需要枚举10000 * 355 * 100次,算下来是三点五亿,常数小的话是有可能过的,但是显然我们不能去赌能不能过,我们来换一种方式枚举。

怎样枚举呢?我们先计算出这一年的前面所有年有多少天(这个好算,枚举每一年,平年就+355, 闰年+356),随后我们再枚举这个月前面所有的月份有多少天,用一个数组来存储每个月有多少天,如果是2月的话需要判断一下年份是否是闰年。

超级简单,没错,主包就是这么水……


代码

#include<iostream>
using namespace std;
int mouths[] ={0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; //每月的天数
int y1, y2, m1, m2, d1, d2;

bool is_leap(int year)
{
    return year % 4 == 0 && year % 100 || year % 400 == 0;
}

int mouthDay(int year, int mouth)
{
    if(mouth == 2) return mouths[2] + is_leap(year);
    return mouths[mouth];
}

int yearDay(int year)
{
    return 365 + is_leap(year);
} 

int dayNums(int year, int mouth, int day)
{
    int l = 0;
    for(int i = 1; i < year; i++)
        l += yearDay(i);
    for(int i = 1; i < mouth; i++)
        l += mouthDay(year, i);
    l += day;
    
    return l;
}

int main()
{
    while(~scanf("%04d%02d%02d\n%04d%02d%02d", &y1, &m1, &d1, &y2, &m2, &d2))
        printf("%d\n", abs(dayNums(y2, m2, d2) - dayNums(y1, m1, d1)) + 1);

    return 0;
}

挤牛奶


分析

这个就更不用多说了,区间合并,主包记得自己最开始学算法的时候第一个真正理解的就是区间合并

具体过程就是先排序,随后每次都用区间去和前一个区间比较能否合并,区间能合并的条件一般是

a[i].r >= a[i].l

特殊情况可能需要左端加一再去比较(就比如我们之前的拿到水管的题目)。

顺便提一嘴这道题用差分前缀和也是可以写的。


代码

// 区间合并
#include<iostream>
#include<vector>
#include<algorithm>
#define s second
#define f first
using namespace std;
typedef pair<int, int> PII;
const int N = 5010;
int n;
PII nums[N];
int onTime, unTime;

int main()
{
    scanf("%d", &n);
    for(int i = 0; i < n; i++)
        scanf("%d%d", &nums[i].f, &nums[i].s);
    sort(nums, nums + n);
    vector<PII> vtr;
    vtr.push_back(nums[0]);
    for(int i = 1; i < n; i++)
        if(vtr.back().s  >= nums[i].f) vtr[vtr.size() - 1].s = max(vtr[vtr.size() - 1].s, nums[i].s);
        else vtr.push_back(nums[i]);
    for(int i = 0; i < vtr.size(); i++)
        onTime = max(onTime, vtr[i].s - vtr[i].f); //
    int t = vtr[0].s;
    for(int i = 1; i < vtr.size(); i++)
        unTime = max(unTime, vtr[i].f - t), t = vtr[i].s;
    printf("%d %d", onTime, unTime);
    return 0;
}

总结

 主包要去休息了,实在是困得不行了,打了一天瞌睡QAQ。


http://www.kler.cn/a/610606.html

相关文章:

  • 【区块链安全 | 第一篇】密码学原理
  • 【linux复习】——进程间通信
  • Flutter 中 GetX 的优缺点及常见问题解决方案
  • Java的DES/CBC/PKCS7Padding加密算法封装类
  • 在线运行vscode
  • 应用服务接口第二次请求一直pending问题
  • qtcreator不能用调试怎么办,打开维护工具,添加Qt Debug Information Files” 这一选项
  • 【区块链安全 | 第五篇】DeFi概念详解
  • LabVIEW多CAN设备连接故障
  • ref和reactive区别
  • Ardupilot开源无人机之Geek SDK进展2025Q2
  • Linux Namespace(网络命名空间)系列二 --- 使用 Open vSwitch 和网络命名空间搭建虚拟网络
  • 2025.03.26【基因数据解析】| BackSPIN:高效基因聚类与过滤工具详解
  • 图的广度优先搜索(BFS)和深度优先搜索(DFS)算法介绍与应用场景以及 C# 代码实现
  • C++蓝桥杯实训篇(一)
  • MySQL数据库表的约束,关联及查询
  • 三方线上美食城|基于Springboot的三方线上美食商城系统
  • 力扣刷题-热题100题-第24题(c++、python)
  • 如何保障kafka的数据不会重复消费呢,如何防止漏掉呢
  • Git的认识安装及创建配置本地仓库