题目:
有n个水桶,第i个水桶里面水的体积为Ai,你可以用1秒时间向一个桶里添加1体积的水。有q次询问,每次询问一个整数pi,你需要求出使其中pi个桶中水的体积相同所花费的最少时间。对于一次询问如果有多种方案,则采用使最终pi个桶中水的体积最小的方案。
例如:
输入:4,3,[1,2,3,4],[2,2,4]
输出:[1,0,5]
说明:
第一次:花费一秒变为 2 2 3 4
第二次:已经存在两个水的体积一样的桶
第三次:花费五秒从2 2 3 4变为4 4 4 4
代码:
思路说明,首先所有的水桶里面的水的体积排序,获得一个有序的序列。
然后已从从要查询的方案里面获取要查询的桶的数量。然后从从水桶里面记录长度选出长度为要查询的数量,如下图的黑框所示。记录一下黑框里面所有的水的体积,用黑框选择的区域里面最后一个水桶的数量乘以选中的水桶的数量减去黑框内所有的水桶的水的体积,就是当前,需要的操作数。选择的区域依次向后移动,然后记录下需要最小的操作数,并且记录一下这个区域的起始位置。然后将这个区域里面所有的水的体积数量改成这个区域最后一个水桶的水的体积。 可以看到,改变前后序列还是有序的。
依次遍历。
class Solution {
public:
/**
* @param n int整型 水桶的个数
* @param q int整型 询问的次数
* @param a int整型vector n个水桶中初始水的体积
* @param p int整型vector 每次询问的值
* @return int整型vector
*/
vector<int> solve(int n, int q, vector<int>& a, vector<int>& p) {
// write code here
vector<int> Resutl(q,0);
sort(a.begin(), a.end());
for(int Counter=0;Counter<q;Counter++){
int tempSum=0,mixValue=0,Index=0;
for(int i=0;i<p[Counter];i++){
tempSum +=a[i];
}
mixValue=a[p[Counter]-1]*p[Counter]-tempSum;
for(int i=p[Counter];i<n;i++){
tempSum -=a[i-p[Counter]];
tempSum +=a[i];
if(a[i]*p[Counter]-tempSum<mixValue){
mixValue=a[i]*p[Counter]-tempSum;
Index=i-p[Counter]+1;
}
}
Resutl[Counter]=mixValue;
for(int i=0;i<p[Counter];i++){
a[i+Index]=a[p[Counter]-1+Index];
}
}
return Resutl;
}
};