左神 中级提升班 2-4
题目
给一个包含n个整数元素的集合a,一个包含m个整数元素的集合b
定义magic操作为,从一个集合中取出一个元素,放到另一个集合里,且操作后两个集合的平均值都大于操作前
返回最多可以进行多少次magic操作
注意以下两点
不可以把一个集合的元素取空,这样就没有平均值了
值为x的元素从集合b取出放入集合a,但集合a中已经有值为x的元素,则a的平均值不变(因为集合元素不重复).
分析
根据两个集合均值是否相同分类讨论
均值相同,假设两个集合的均值都是100,如果a把小于100的数字给b,那么b的均值会减小,如果a把100给b,那么a和b的均值不变,如果a把大于100的数组给b,那么a的均值减小,所以均值相同,无论做什么magic操作,都不会满足题意
均值不同,mean(a)=50,mean(b)=100,如果a把小于50的数字给b,那么b的均值会减小,如果a把50给b,a的均值不变,如果a把大于50的数字给b,那么a的均值减小,所以不能从均值小的集合里拿数字给均值大的集合,只能从均值大的集合里拿数字给均值小的集合,从b里取一个(50,100)范围内的数字给a即可满足题意;假设b集合里有60,70,80,90这几个数字,我们先拿哪一个数字呢?我们先假设拿60,这样b集合得到了最大幅度的提升(假设到了150),a得到了最小幅度的提升(假设到了55),这样下次就可以从b里取更大范围的数字了,就可以做更多的magic操作了
import java.util.*; class Solution { /** * @param arr1 第一个集合 * @param arr2 第二个集合 * @return 移动数字让两个集合的均值都上升,最多可以又一次这种操作 */ public int f(int[] arr1, int[] arr2) { //1 double sum1 = 0, sum2 = 0; for (int i = 0; i < arr1.length; i++) { sum1 += (double) arr1[i]; } for (int i = 0; i < arr2.length; i++) { sum2 += (double) arr2[i]; } //2 if (avg(sum1, arr1.length) == avg(sum2, arr2.length)) { return 0; } //3 int[] arrLess = null, arrMore = null; //update double sumLess = 0, sumMore = 0; if (avg(sum1, arr1.length) < avg(sum2, arr2.length)) { arrLess = arr1; arrMore = arr2; sumLess = sum1; sumMore = sum2; } else { arrLess = arr2; arrMore = arr1; sumLess = sum2; sumMore = sum1; } Arrays.sort(arrMore); //update int lessSize = arrLess.length, moreSize = arrMore.length; //update HashSet<Integer> setLess = new HashSet<>(); //update int ans = 0; for (int i = 0; i < arrMore.length; i++) { double cur = (double) arrMore[i]; if (cur > avg(sumLess, lessSize) && cur < avg(sumMore, moreSize) && !setLess.contains(cur)) { sumMore -= cur; moreSize--; sumLess += cur; lessSize++; setLess.add(arrMore[i]); ans++; } } return ans; } private double avg(double sum, int size) { return sum / (double) size; } }