B - 更换电池
问题描述
Bob有一部旧式的收音机,收音机要放两节电池才能工作。他发现有个广播台在全天播放相声,为了尽可能长时间的听相声,Bob买了很多电池给收音机供电,这些电池质量不同,因而使用时长也不同,有的能使用7个小时,有的可能就只能使用4个小时。显然如果他只有两节电池一个能用7小时一个能用4小时,那么他只能听4个小时的相声,那7小时的电池剩下的3小时的电量无法使用,但是如果他有更多的电池,就可以更加充分地利用它们,比如他有三节电池分别能用4、4、7小时,他可以先使用两节能用4个小时的电池,使用半个小时后再把其中一个换成能使用7个小时的电池,3.5小时后其中一节的电量耗尽,再把剩下的一节电池换成刚才换下的电池(那个电池还能用3.5个小时),这样收音机总共就可以使用0.5+3.5+3.5=7.5个小时,就没有造成浪费。
现在已知电池的数量和各电池能够使用的时间,请你帮助Bob计算一下最多能听几个小时的广播。
数据输入
输入多组数据,每组数据有两行,第1行有一个整数N,代表Bob的电池的个数,第二行有N个正整数,表示各颗电池能使用的时间
- 1 ≤ N ≤1000
- 电池的使用时间是[1,230]范围内的正整数
数据输出
对每组数据输出一行,分别表示Bob能听广播的时长,保留到小数点后1位。
样例1
样例1
输入样例
2
7 4
3
4 4 7
输出样例
4.0
7.5
提示
要使用EOF判断输入数据的结束
这是一个很优秀的贪心题,比较难想
解析:
这个题想了很久,首先,知道这种题要么是贪心,要么是有数学规律或计算规律,要么就是单纯模拟(这个题显然不是)。
找规律是找到了,每次选择最大的两个去使用,一直如此即可,最终的值就是答案。
但问题也很明显,不能每次选择一下,两个电池减0.5(甚至是0.1)我都再排一下序,找到最大的两个值...
想了很久,放弃这个思路...
那么,贪心:假设有一个超级电池M,规定其他电池单值都不如它多
1.如果其他所有电池加起来SUM都不如它,那么显然ANS=其他电池之和SUM
2.如果其他电池加起来SUM比它多,那么其他电池总是可以两两抵消(或更多的方式抵消),使得最终SUM=M,并最终抵消所有电量,那么就是没有浪费的,所有电池电量都用完!所以ANS=所有电池之和/2
上代码:(显然,排序后的最后一个电池,就是我们要找的超级电池!)
import java.util.Arrays;
import java.util.Scanner;
public class Main{
public static void main(String args[]){
Scanner sc = new Scanner(System.in);
while(sc.hasNext()) {
int n = sc.nextInt();
long arr[] = new long[n];
for (int i = 0; i < arr.length; i++) {
arr[i] = sc.nextLong();
}
Arrays.sort(arr);
double ans = 0;
for (int i = 0; i < arr.length-1; i++) {
ans += arr[i];
}
if(ans<arr[arr.length-1]) {
System.out.println(ans);
}else {
System.out.println((ans+arr[arr.length-1])/2);
}
}
}
}