六年级蒟蒻来题解了
题目大意
有一道题詹和他的朋友都不会做,然后呢就要求你去完成(真够呛的)(前面都是废话)。告诉你有t组样例每组样例中有一个n和n个数。你可以完成一下亿种操作:
选定一个 i ,这个i的范围是1~n-1,你可以把第 i 个位置减 1,但是与此同时第 i+1 个点必须得加 1 。你可以操作无限次,最后得以保证这些数中的最大数减去最小的数的值最小。
解题思路
首先我们可以把它的每一次操作看成把第 i 号位置的 1 放到了 i+1 里面。我们再来想我们想,既然要让它数组的最大一个数减去最低一个数是最小的,那是不是把这些尽可能的平均一点移多补少是不是就行了呢?答案是肯定的。所以我们可以用一个单调栈去模拟这个过程每一次只要栈里面有数并且平均数大于这数就行了。
AC代码:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int main(){
int t=1;
cin>>t;
while(t--){
int n;
cin>>n;
vector<ll> v(n+1);
for(int i=1;i<=n;i++){
cin>>v[i];
}
stack<pair<ll,int>> s;
for(int i=1;i<=n;i++){
ll sum=v[i],cot=1;
while(!s.empty()&&s.top().first>=sum/cot){
sum+=s.top().first*s.top().second;
cot+=s.top().second;
s.pop();
}
s.push({sum/cot,cot-sum%cot});
if(sum%cot!=0){
s.push({sum/cot+1,sum%cot});
}
}
ll mx=s.top().first;
while(s.size()>1){
s.pop();
}
cout<<mx-s.top().first<<'\n';
}
}
小赞赞为什么不见了!!