喝咖啡-间隔插空

本文介绍了一个算法,用于计算在特定条件下一个月内最多可以喝咖啡的天数,考虑到必须喝咖啡的固定日期和自我设定的最小间隔天数。

题目

X很喜欢喝咖啡但是别人告诉他经常喝咖啡不好,X决定限制自己喝咖啡的间隔天数不小于K。但是每月(按30天计)有某些日子一定要喝咖啡,求X一个月最多能喝多少天咖啡。

输入:

第一行为样例数,接下来每两行代表一个样例,样例中的第一行两个正整数K、M分别表示喝咖啡的间隔天数和每个月一定要喝的日子的天数;

第二行表示需要喝咖啡的日期,日期之间用空格分隔。

输出:最多能喝咖啡的天数。

样例:

输入:

4

0 10

1 2 3 4 5 6 7 8 9 10

1 15

1 3 5 7 9 11 13 15 17 19 21 23 25 27 29

1 7

5 9 13 17 21 25 29

1 0

 

输出:

30

15

15

15

说明:第二行0 10,分别表示至少间隔0天可以喝咖啡,其中有10天一定要喝,日期分别是第二行的十个数,输出结果30表示一个月最多有30天可以喝咖啡(间隔0天就是天天都可以喝啦~~)

分析

1、特殊情况:如果间隔天数K=0,直接输出30;

2、正常情况:间隔天数K>0:

首先,我们知道,可以喝咖啡的天数res>=M ( M是题中给出的一定会喝的天数,且保证满足条件间隔K天 )

那么现在,我们要解决的问题是,一定要喝咖啡的两个日期中间,还有多少天可以和咖啡呢?

比如第三个样例,间隔天数K=1,5号和9号之间,只有7号一天满足条件,所以 此时,res=7+1=8;

9号和13号之间,只有11号一天满足条件,所以 res=8+1=9;

...

我们只要算出每两个数中间可以插入多少个数,就可以了。

穷举我当然知道啦,那怎么算嘛?--来,坐下~

算法

样例,输入:

1 7

5 9 13 17 21 25 29

输出:

15

①一开始,我们就知道可以喝咖啡的天数res>=7=M,题目都给了嘛,这就不用算了,肯定要喝的嘛。

②怎么算可以在两个数之间插入的个数呢?举例,5 和9:

5_ _ _9

我们可以知道,间隔1天可以喝咖啡,则,每2天最多可以喝一次,5号到9号是9-5=4天,5号喝了,所以,6,7,8,9号四天中,有4/2=2天(即7号和9号)可以喝咖啡,但是,9号我们在最上面就算过了(最开始res=M时,就包含了数组中原有的9号),所以少算一天,res +=(9-5)/(1+1)-1=1,即 res +=(arr[i+1]-arr[i])/(K+1)-1天,此时,res =7+1=8

③9和13之间也一样,9_ _ _ 13,也是res +=(13-9)/(1+1)-1=1,res=8+1=9

...

一直算到25和29之间,此时res = 13.(给出的数组+[7,11,15,19,23,27]这六天)

④咦?答案不是15吗?是的,别忘了,还有1-4号和30号我们还没考虑。

其中,29号喝了咖啡,30号就不能喝了。

1-4号呢?我们知道,1和3号是满足条件可以喝咖啡的。res = 13 +2=15,就是答案。

那么,2是怎么来的呢?

原理相同,1-4号之间可以喝咖啡的天数day= (5-1)/(1+1)=(arr[0]-1)/(K+1)=2,这里需要减1吗?--不需要

what ???为什么?????因为上面9号我们都在最初的数组中计数了,而这里1,3号,数组中都没有出现过。

其实,29号到月末也是一样的原理,day= (30-29)/(1+1)=(arr[0]-1)/(K+1)=0,如果有31号,那么,day = day= (31-29)/(1+1)=1,恩,31号的确可以喝咖啡,当然,这里题目说没有31号。

代码如下:

import java.util.Scanner;
public class Main {
	public static void main(String args[]) {
		Scanner sc = new Scanner(System.in);
		int T = Integer.parseInt(sc.nextLine());
		for(int i=0;i<T;i++){
			int K = sc.nextInt();
			int M = sc.nextInt();
			sc.nextLine();
                        //天数K==0
			if(K==0){
				System.out.println(30);
			}
			else{
				int res = M;
				String[] ss = sc.nextLine().split(" ");
				int [] arr = new int[ss.length];
				for(int j=0;j<M;j++){
					arr[j] = Integer.parseInt(ss[j]);
				}
				int start = 1 , end ;
				for(int j=0;j<M;j++){
					end =arr[j];
					res += new Main().count(start,end,K);
					start = end;
				}
                                //单独算最后一个一定要喝咖啡的日期到30号的天数
				res += (30-start)/(K+1);
				System.out.println(res);
			}	
		}
	}
        //计算两个日期之间有多少天可以喝咖啡
	public int count(int start, int end, int k){
		if(start>=end)
			return 0;
                //兼容了从1号开始到第一个一定要喝咖啡的日期
		return (end-start)/(k+1)+(start==1?0:-1);
	}
}

说明

为什么我们计算 从1号开始到第一个一定要喝咖啡的日期 之间的天数和其他情况合并,而要单独计算 最后一个一定要喝咖啡的日期到30号的天数 不合并呢?头和尾的情况不是一样的吗?

是的,但是,arr里可能没有30号呀,so,end可能永远都不等于30。所以我们自力更生,计算一下就可以啦~~

内容概要:本文详细介绍了一个基于C++的养老院管理系统的设计与实现,旨在应对人口老龄化带来的管理挑战。系统通过整合住户档案、健康监测、护理计划、任务调度等核心功能,构建了从数据采集、清洗、AI风险预测到服务调度与可视化的完整技术架构。采用C++高性能服务端结合消息队列、规则引擎和机器学习模型,实现了健康状态实时监控、智能任务分配、异常告警推送等功能,并解决了多源数据整合、权限安全、老旧硬件兼容等实际问题。系统支持模块化扩展与流程自定义,提升了养老服务效率、医护协同水平和住户安全保障,同时为运营决策提供数据支持。文中还提供了关键模块的代码示例,如健康指数算法、任务调度器和日志记录组件。; 适合人群:具备C++编程基础,从事软件开发或系统设计工作1-3年的研发人员,尤其是关注智慧养老、医疗信息系统开发的技术人员。; 使用场景及目标:①学习如何在真实项目中应用C++构建高性能、可扩展的管理系统;②掌握多源数据整合、实时健康监控、任务调度与权限控制等复杂业务的技术实现方案;③了解AI模型在养老场景中的落地方式及系统架构设计思路。; 阅读建议:此资源不仅包含系统架构与模型描述,还附有核心代码片段,建议结合整体设计逻辑深入理解各模块之间的协同机制,并可通过重构或扩展代码来加深对系统工程实践的掌握。
内容概要:本文详细介绍了一个基于C++的城市交通流量数据可视化分析系统的设计与实现。系统涵盖数据采集与预处理、存储与管理、分析建模、可视化展示、系统集成扩展以及数据安全与隐私保护六大核心模块。通过多源异构数据融合、高效存储检索、实时处理分析、高交互性可视化界面及模块化架构设计,实现了对城市交通流量的实时监控、历史趋势分析与智能决策支持。文中还提供了关键模块的C++代码示例,如数据采集、清洗、CSV读写、流量统计、异常检测及基于SFML的柱状图绘制,增强了系统的可实现性与实用性。; 适合人群:具备C++编程基础,熟悉数据结构与算法,有一定项目开发经验的高校学生、研究人员及从事智能交通系统开发的工程师;适合对大数据处理、可视化技术和智慧城市应用感兴趣的技术人员。; 使用场景及目标:①应用于城市交通管理部门,实现交通流量实时监测与拥堵预警;②为市民出行提供路径优化建议;③支持交通政策制定与信号灯配时优化;④作为智慧城市建设中的智能交通子系统,实现与其他城市系统的数据协同。; 阅读建议:建议结合文中代码示例搭建开发环境进行实践,重点关注多线程数据采集、异常检测算法与可视化实现细节;可进一步扩展机器学习模型用于流量预测,并集成真实交通数据源进行系统验证。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值