1330: PIPI的乐高积木

题目描述

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;
}
发布了78 篇原创文章 · 获赞 7 · 访问量 4565

猜你喜欢

转载自blog.csdn.net/weixin_44433678/article/details/104687112