题目来源
中北大学2018年新生赛
问题描述
LQW有n堆糖,每堆糖的个数为a[1],a[2]....a[n],但她是一个强迫症患者,她想要每堆糖的个数都相同。
当她正准备行动的时候,LYF过来说:”如果你每次能将其中俩堆糖各加一个糖,如果最终你将每堆加成相同的个数,且使这个数最小,你将最终的个数和你加的次数告诉我,如果正确的话,我就会给你补上这些糖“。
LQW想了想,白给的糖谁不想要,但是她不知道怎样加,所以想要求祝你,希望你能帮她得到这些糖。
输入描述
第一行输入一个n(1<=n<=10000,n为奇数)
第二行输入n个数字,代表第i堆的个数为a[i](0<=a[i]<=100)
输出描述
输出最终的个数和需要加的次数。
样例输入
5
1 2 3 4 5
样例输出
5 5
题解
这道题模拟一下就行了,我先说一下我的想法,虽然麻烦了点。 我用优先队列和multiset模拟的,每次从优先队列取出两个最小值a,b弹出,同时也在multiset里删除了。然后 a++,b++,再把a,b放到优先队列和multiset里,知道multiset里的数全都一样了,就结束。multiset里的元素全都一样时*s.begin()==*(--s.end())。 2015年新生赛队列极值那道题也可以用queue和multiset模拟一下就过了。
然而这道题不用multiset也可以做出来,我想的麻烦了,刚开始就求一下和是多少,每次队列弹出两个元素,看他两乘n和总和相等吗,不相等那么这两个加一放进去,总和加二,继续模拟。
下边给出用multiset和不用multiset的两份代码。
#include<algorithm>
#include <iostream>
#include<cstring>
#include <cstdio>
#include<queue>
#include<set>
using namespace std;
typedef long long ll;
priority_queue<int,vector<int> ,greater<int> > q;
multiset<int> s;
int n,x;
int main(){
cin>>n;
for(int i=0;i<n;i++){
scanf("%d",&x);
q.push(x);
s.insert(x);
}
int cnt=0;
while(*s.begin()!=*(--s.end())){
cnt++;
int a=q.top(); q.pop();
int b=q.top();q.pop();
s.erase(s.find(a));
s.erase(s.find(b));
a++;b++;
q.push(a);
q.push(b);
s.insert(a);
s.insert(b);
}
printf("%d %d\n",*s.begin(),cnt);
return 0;
}
#include<algorithm>
#include <iostream>
#include<cstring>
#include <cstdio>
#include<queue>
using namespace std;
typedef long long ll;
priority_queue<int,vector<int> ,greater<int> > q;
int n,x;
int main(){
cin>>n;
int sum=0;
for(int i=0;i<n;i++){
scanf("%d",&x);
q.push(x);
sum+=x;
}
int cnt=0;
while(true){
int a=q.top(); q.pop();
int b=q.top();q.pop();
if(a*n==sum&&b*n==sum){
break;
}
a++;b++;
q.push(a);
q.push(b);
cnt++;
sum+=2;
}
printf("%d %d\n",sum/n,cnt);
return 0;
}