题目描述
PIPI有一堆乐高小积木,小积木刚好是1x1x1的立方体,POPO把这些立方体垒起来组成了N根柱子。
POPO搭的柱子高度参差不齐,PIPI认为这并不美观,PIPI将N根柱子的美观度定义为最高柱子和最矮柱子的差,这个值越小越美观。
PIPI为了让柱子变得美观,他每次可以从某根柱子上拿下一个乐高积木放到另一根柱子上(两根柱子不能是同一根)。PIPI可以进行不超过k次的移动操作,请问这N根柱子能够达到的最小美观度是多少?
输入
第一行输入两个数N,k (2<=N<=1e5, 0<=k<=5000) 表示柱子的数量以及PIPI最多进行的移动次数。
第二行输入N根柱子的初始高度(1<=hi<=1e4)。
输出
第一行输出两个数字 a b。代表最小美观度和到达该美观度最少的移动次数。
接下来b行,每行两个数x和y,代表将x柱子上的立方体放到y上。
若x有多种选择,那么选择编号尽可能大的x,若y有多种选择,那么选择编号尽可能小的y(柱子编号从1~N)。
样例输入
3 2
5 8 5
样例输出
0 2
2 1
2 3
#include<bits/stdc++.h>
using namespace std;
struct bar
{
int h,id;
bool operator<(const bar&rs)const
{
if(h==rs.h) return id<rs.id;
return h<rs.h;
}
};
set<bar> s;
vector<pair<int,int> >mov;
int main()
{
int n,k,h;
scanf("%d%d",&n,&k);
for(int i=1;i<=n;i++)
{
scanf("%d",&h);
s.insert({h,i});
}
set<bar>::iterator it;
int ans=k; ///ans赋初值为k,因为当不存在h2-h1小于等于1时,ans的值为k,如7--5
for(int i=0;i<k;i++)
{
it=s.end();
if(it!=s.begin()) --it;
int h1=(*s.begin()).h,h2=(*it).h;
int id1=(*s.begin()).id,id2=(*it).id;
if(h2-h1<=1){
ans=i;
break;
}
s.erase(*s.begin());
s.erase(*it);
s.insert({h1+1,id1});
s.insert({h2-1,id2});
mov.push_back({id2,id1});
}
it=s.end();
if(it!=s.begin()) --it;
int h1=(*s.begin()).h,h2=(*it).h;
printf("%d %d\n",h2-h1,ans);
for(int i=0;i<mov.size();i++)
printf("%d %d\n",mov[i].first,mov[i].second);
return 0;
}