前言
工作了十几年,从普通的研发工程师一路成长为研发经理、研发总监。临近40岁,本想辞职后换一个相对稳定的工作环境一直干到老, 没想到离职后三个多月了还没找到工作,愁肠百结。为了让自己有点事情做,也算提高一下自己的编程能力,无聊之余打算用一些大厂的编程题练练手。希望通过这些分享能够帮到一些人,也希望能和看到此文的大神们沟通交流,提升自己,更希望在此期间能够找到一份理想的工作。
题目描述
近些年来,我国防沙治沙取得显著成果。某沙漠新种植N棵胡杨(编号1-N),排成一排。
一个月后,有M棵胡杨未能成活。
现可补种胡杨K棵,请问如何补种(只能补种,不能新种),可以得到最多的连续胡杨树?
输入
N 总种植数量,1 <= N <= 100000
M 未成活胡杨数量,M 个空格分隔的数,按编号从小到大排列,1 <= M <= N
K 最多可以补种的数量,0 <= K <= M
输出
最多的连续胡杨棵树。
示例
示例1
输入
5
2
2 4
1
输出3
说明
补种到2或4结果一样,最多的连续胡杨棵树都是3
示例2
输入
10
3
2 4 7
1
输出6
说明
种第7棵树,最多连续胡杨树棵数位6(5,6,7,8,9,10)
解题思路
分段长度计算总和法,将分割的距离分段,并记录长度, 计算连续x个的最大值。
题解
Java实现
package huawei.e100;
import java.util.Arrays;
import java.util.Scanner;
/**
* @author arnold
* @date 2024年12月23日
* 补种未成活胡树
*/
public class T36 {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
while(sc.hasNext()) {
// 读取总共的胡杨树数量
int total = sc.nextInt();
// 读取未成活的胡杨树数量
int deadCount = sc.nextInt();
int[] deads = new int[deadCount];
// 根据输入,将未成活的树的位置标记为1
for (int i = 0; i < deadCount; i++) {
deads[i] = sc.nextInt();
}
// 读取可以补种的树的数量
int supplementCount = sc.nextInt();
int maxLen = run(total, deadCount, deads, supplementCount);
System.out.println(maxLen);
}
}
//分段长度计算总和法,将分割的距离分段,并记录长度, 计算连续x个的最大值
static int run(int total, int deadCount, int[] deads, int supplementCount) {
int left = 0;
// 计算分割后各段的长度
int[] lens = new int[deadCount +1];
for (int i = 0; i < lens.length-1; i++) {
lens[i] = deads[i] - left -1;
left = deads[i];
}
lens[lens.length-1] = total - deads[deadCount-1];
// 计算相邻的几个可补位置的种上后的连续长度,并取最大值
int maxLen = 0;
for (int i = 0; i < lens.length - supplementCount; i++) {
int sum = supplementCount;
//可补数+1个段相加, 再加可补数 即为连续的棵数
for (int j = 0; j <= supplementCount; j++) {
sum += lens[i+j];
}
maxLen = Math.max(maxLen, sum);
}
return maxLen;
}
}