最短木板长度_100分_A卷_贪心策略

最短木板长度

题目描述:

  小明有 n 块木板,第 i ( 1 ≤ i ≤ n ) 块木板长度为 ai。
  小明买了一块长度为 m 的木料,这块木料可以切割成任意块,
  拼接到已有的木板上,用来加长木板。
  小明想让最短的木板尽量长。
请问小明加长木板后,最短木板的长度可以为多少?

输入输出描述:

输入描述:

  输入的第一行包含两个正整数,n(1≤n≤103),m(1≤m≤106)
  n表示木板数,m表示木板长度。输入的第二行包含n个正整数,a1,a2,…an(1≤ai≤10^6)。

输出描述:

  输出的唯一一行包含一个正整数,表示加长木板后,最短木板的长度最大可以为多少?

示例1:

输入:
	5 3
	4 5 3 5 5
输出:
	5

说明:
	给第1块木板长度增加1,给第3块木板长度增加2后,
	这5块木板长度变为[5,5,5,5,5],最短的木板的长度最大为5。

示例二:

输入:
	5 2
	4 5 3 5 5
输出:
	4
说明:
	给第3块木板长度增加1后,
	这5块木板长度变为[4,5,4,5,5],剩余的木料长度为1。
	此时剩余木料无论给哪块木板加长,最短木料的长度都为4。

解题思路:

谈心策越:
分2种情况:
1、如果所有木板长度一样,就把木料的均分都每一块木板上
2、如果所有木板长度不一样,就排序,计算出第一短和第二短的木板的长度差,将木料都先不再第一短的所有木板上。如果木料长度不够将所有最短的木板长度调整为第二短,那么可直接结束循环。如果木料还有剩余,则继续按照这两种情况循环继续分割木料。

代码:

public static void main(String[] args) {
	Scanner scanner = new Scanner(System.in);
	String[] split = scanner.nextLine().split(" ");
	int n = Integer.parseInt(split[0]);
	int m = Integer.parseInt(split[1]);
	int[] nums = new int[n];
	
	//处理输入
	split = scanner.nextLine().split(" ");
	for (int i = 0; i < n; i++) {
		nums[i] = Integer.parseInt(split[i]);
	}

	if (n == 1) {
		System.out.println(nums[0] + m);
		return;
	}

	while (m > 0) {
		// 排序
		Arrays.sort(nums);

		// 给最短的木板数量
		int index = 1;
		while (index < n && nums[index - 1] == nums[index]) {
			index++;
		}

		// 如果长度都一样,把 m 均分,接在每一块板子上
		if (index == n) {
			System.out.println(m / n + nums[0]);
			return;
		} else {
			// 最短和第二短之间相差多少米
			int diff = nums[index] - nums[index - 1];

			if (index * diff <= m) {
				// 让最短和第二短的木板长度一致
				m -= index * diff;
				while (index > 0) {
					nums[--index] += diff;
				}
			} else {
				// m 长度不足以让最短和第二短的木板长度一致
				System.out.println(nums[0] + m / index);
				return;
			}
		}
	}

	System.out.println(nums[0]);
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值