喝咖啡-间隔插空

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

题目

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。所以我们自力更生,计算一下就可以啦~~

【电力系统】单机无穷大电力系统短路故障暂态稳定Simulink仿真(带说明文档)内容概要:本文档围绕“单机无穷大电力系统短路故障暂态稳定Simulink仿真”展开,提供了完整的仿真模型与说明文档,重点研究电力系统在发生短路故障后的暂态稳定性问题。通过Simulink搭建单机无穷大系统模型,模拟不同类型的短路故障(如三相短路),分析系统在故障期间及切除后的动态响应,包括发电机转子角度、转速、电压和功率等关键参数的变化,进而评估系统的暂态稳定能力。该仿真有助于理解电力系统稳定性机理,掌握暂态过程分析方法。; 适合人群:电气工程及相关专业的本科生、研究生,以及从事电力系统分析、运行与控制工作的科研人员和工程师。; 使用场景及目标:①学习电力系统暂态稳定的基本概念与分析方法;②掌握利用Simulink进行电力系统建模与仿真的技能;③研究短路故障对系统稳定性的影响及提高稳定性的措施(如故障清除时间优化);④辅助课程设计、毕业设计或科研项目中的系统仿真验证。; 阅读建议:建议结合电力系统稳定性理论知识进行学习,先理解仿真模型各模块的功能与参数设置,再运行仿真并仔细分析输出结果,尝试改变故障类型或系统参数以观察其对稳定性的影响,从而深化对暂态稳定问题的理解。
本研究聚焦于运用MATLAB平台,将支持向量机(SVM)应用于数据预测任务,并引入粒子群优化(PSO)算法对模型的关键参数进行自动调优。该研究属于机器学习领域的典型实践,其核心在于利用SVM构建分类模型,同时借助PSO的全局搜索能力,高效确定SVM的最优超参数配置,从而显著增强模型的整体预测效能。 支持向量机作为一种经典的监督学习方法,其基本原理是通过在高维特征空间中构造一个具有最大间隔的决策边界,以实现对样本数据的分类或回归分析。该算法擅长处理小规模样本集、非线性关系以及高维度特征识别问题,其有效性源于通过核函数将原始数据映射至更高维的空间,使得原本复杂的分类问题变得线性可分。 粒子群优化算法是一种模拟鸟群社会行为的群体智能优化技术。在该算法框架下,每个潜在解被视作一个“粒子”,粒子群在解空间中协同搜索,通过不断迭代更新自身速度与位置,并参考个体历史最优解和群体全局最优解的信息,逐步逼近问题的最优解。在本应用中,PSO被专门用于搜寻SVM中影响模型性能的两个关键参数——正则化参数C与核函数参数γ的最优组合。 项目所提供的实现代码涵盖了从数据加载、预处理(如标准化处理)、基础SVM模型构建到PSO优化流程的完整步骤。优化过程会针对不同的核函数(例如线性核、多项式核及径向基函数核等)进行参数寻优,并系统评估优化前后模型性能的差异。性能对比通常基于准确率、精确率、召回率及F1分数等多项分类指标展开,从而定量验证PSO算法在提升SVM模型分类能力方面的实际效果。 本研究通过一个具体的MATLAB实现案例,旨在演示如何将全局优化算法与机器学习模型相结合,以解决模型参数选择这一关键问题。通过此实践,研究者不仅能够深入理解SVM的工作原理,还能掌握利用智能优化技术提升模型泛化性能的有效方法,这对于机器学习在实际问题中的应用具有重要的参考价值。 资源来源于网络分享,仅用于学习交流使用,请勿用于商业,如有侵权请联系我删除!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值