小易有一些立方体,每个立方体的边长为1,他用这些立方体搭了一些塔。
现在小易定义:这些塔的不稳定值为它们之中最高的塔与最低的塔的高度差。
小易想让这些塔尽量稳定,所以他进行了如下操作:每次从某座塔上取下一块立方体,并把它放到另一座塔上。
注意,小易不会把立方体放到它原本的那座塔上,因为他认为这样毫无意义。
现在小易想要知道,他进行了不超过k次操作之后,不稳定值最小是多少。
第一行两个数n,k (1 <= n <= 100, 0 <= k <= 1000)表示塔的数量以及最多操作的次数。
第二行n个数,ai(1 <= ai <= 104)表示第i座塔的初始高度。
第一行两个数s, m,表示最小的不稳定值和操作次数(m <= k)
接下来m行,每行两个数x,y表示从第x座塔上取下一块立方体放到第y座塔上。
3 2 5 8 5
0 2 2 1 2 3
mport java.util.*;
public class Main {
public static void main(String[] args)
{
Scanner sc=new Scanner(System.in);
int n=sc.nextInt();//塔的数量
int k=sc.nextInt();//最多操作数
ArrayList<Integer> towers=new ArrayList<>();
for (int i=0;i<n;i++)
towers.add(sc.nextInt());
int count=0;
int max=Collections.max(towers);
int min=Collections.min(towers);
ArrayList<Integer> list1=new ArrayList<>();
ArrayList<Integer> list2=new ArrayList<>();
while (max-min>1&&count<k)
{
max=Collections.max(towers);min=Collections.min(towers);
list1.add(towers.indexOf(max)+1);list2.add(towers.indexOf(min)+1);
towers.set(towers.indexOf(min),min+1);
towers.set(towers.indexOf(max),max-1);
count++;
}
System.out.println(Collections.max(towers)-Collections.min(towers)+" "+count);
for (int i=0;i<list1.size();i++)
{
System.out.println(list1.get(i)+" "+list2.get(i));
}
}
}
java的collection的函数各种调用,思路和上面答案差不多,利用函数使代码更加简洁
import java.util.*;
public class Main {
static class Tower {
int height;
int index;
public Tower(int height, int index) {
this.height = height;
this.index = index;
}
}
public static class TowerComparator implements Comparator<Tower> {
public int compare(Tower t1, Tower t2) {
return t1.height - t2.height;
}
}
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
int k = sc.nextInt();
Tower[] towers = new Tower[n];
for (int i = 0; i < n; i++) {
towers[i] = new Tower(sc.nextInt(), i + 1);
}
List<String> lists = new ArrayList<>();
Arrays.sort(towers, new TowerComparator());
int count = 0;
while (towers[n - 1].height - towers[0].height > 0 && k > 0) {
towers[n - 1].height--;
towers[0].height++;
k--;
count++;
lists.add(towers[n - 1].index + " " + towers[0].index);
Arrays.sort(towers, new TowerComparator());
}
System.out.println((towers[n - 1].height - towers[0].height) + " " + count);
for (int i = 0; i < lists.size(); i++) {
System.out.println(lists.get(i));
}
}
}
import java.util.ArrayList;import java.util.Scanner;public class Main {public static void main(String[] args) {Scanner scan = new Scanner(System.in);int n = scan.nextInt();//塔数int k = scan.nextInt();//最多可操作数int[] height = new int[n];//塔的高度for (int i = 0; i < n; i++) {height[i] = scan.nextInt();}int count = 0;ArrayList<Integer> list1 = new ArrayList<Integer>();ArrayList<Integer> list2 = new ArrayList<Integer>();for (int i = 0; i < k; i++) {int h = max(height);//找到最高的int l = min(height);//找到最低的if(balance(height[h],height[l])) {break;}count++;height[h]--;height[l]++;list1.add(h+1);list2.add(l+1);}System.out.println(height[max(height)]-height[min(height)]+" "+count);for (int i = 0; i < list1.size(); i++) {System.out.println(list1.get(i)+" "+list2.get(i));}}public static int max(int[] height) {//返回最高塔的下标int h = 0;int max = height[0];for (int i = 1; i < height.length; i++) {if(max<height[i]) {h = i;max = height[i];}}return h;}public static int min(int[] height) {//返回最低塔的下标int l = 0;int min = height[0];for (int i = 1; i < height.length; i++) {if(min>height[i]) {l = i;min = height[i];}}return l;}public static boolean balance(int hval,int lval){//判断是否平衡boolean flag = false;int x = hval-lval;if(x<=1)flag = true;return flag;}}
策略很简单,就是每次把最高的塔拆一个到最低的上面,题目的坑在于,如果最后几步的不稳定值没变,可以选择不做最后几步
#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
#include <bitset>
#include <unordered_map>
#include <stack>
#include <queue>
#include <deque>
#include <limits>
#include <cstdio>
using namespace std;
int main()
{
int n, k;
cin>>n>>k;
vector<int> res, h(n, 0), st;
for(int i=0; i<n; ++i) cin>>h[i];
while(1){
auto b=h.begin(), s=h.begin();
for(auto it = h.begin(); it != h.end(); ++it){
if(*it > *b) b = it;
if(*it < *s) s = it;
}
st.push_back(*b - *s);
if(st.size()>k || *b - *s < 2) break;
res.push_back(b - h.begin() + 1);
res.push_back(s - h.begin() + 1);
--*b; ++*s;
}
while(st.size()>1 && *(st.end()-2) == *(st.end()-1))
st.pop_back();
int m = st.size() - 1;
cout<<st.back()<<' '<<m<<endl;
for(int i=0; i<m; ++i){
cout<<res[2*i]<<' '<<res[2*i+1]<<endl;
}
}
#include<bits/stdc++.h>
using namespace std;
bool op(const pair<int, int>a, const pair<int, int>b);
int main() {
int n, k, x, s, m = 0;
cin >> n >> k;
vector<pair<int, int>>a, res;
for (int i = 0; i<n; i++) {
cin >> x;
a.push_back(make_pair(i, x));
}
sort(a.begin(), a.end(), op);
while (k--) {
if (a[n - 1].second>a[0].second) {
m++;
a[n - 1].second--;
a[0].second++;
res.push_back(make_pair(a[n - 1].first+1, a[0].first+1));
sort(a.begin(), a.end(), op);
}
else break;
}
s = a[n - 1].second - a[0].second;
cout << s <<" "<< m << endl;
for (int i = 0; i<m; i++) {
cout << res[i].first << " " << res[i].second << endl;
}
return 0;
}
bool op(const pair<int, int>a, const pair<int, int>b) {
return a.second<b.second;
} # -*- coding: utf-8 -*-
# 为后面排序定义一个方法
def by_value(t):
return t[1]
# 读入数据
n,k = list(map(int, input().split()))
A = list(map(int, input().split())) # A = [a1,a2,a3,...an]
#eg:
#n,k = [3,2]
#A = [5,8,5]
# A_ = [[1, 5], [2, 8], [3, 5]] 其中每个元素表示:[第i堆,对应塔数]
A_ = [list(i) for i in zip (range(1,len(A)+1),A)]
# 先对A_从大到小排一次序
sorted_A =sorted(A_, key = by_value, reverse = True)
count = 0
move_record = [] # 缓存搬移的记录
while sorted_A[0][1]-1 >= sorted_A[-1][1]+1 and count+1 <= k:
max_index = sorted_A[0][0]
min_index = sorted_A[-1][0]
sorted_A[0][1] -=1 # 从最多堆搬走一个
sorted_A[-1][1] +=1 # 往最少堆搬来一个
count +=1
move_record.append([max_index, min_index])
sorted_A = sorted(sorted_A, key = by_value, reverse = True)
s = sorted_A[0][1]-sorted_A[-1][1] # s:最小的不稳定值,即最小的差
print('{} {}'.format(s,count))
for i in move_record:
print('{} {}'.format(i[0],i[1])) n, k = map(int, input().split())
a = list(map(int, input().split()))
res_list = []
for i in range(k):
max_index = a.index(max(a))
min_index = a.index(min(a))
res_list.append([max_index+1, min_index+1])
a[max_index] -= 1
a[min_index] += 1
if max(a) - min(a) < 2:
break
print("%d %d" % (max(a)-min(a), len(res_list)))
for i in range(len(res_list)):
print("%d %d" % (res_list[i][0], res_list[i][1]))
import java.util.Comparator;
import java.util.PriorityQueue;
import java.util.Scanner;
class Tal {
int h, index;
Tal(int h, int index) {
this.h = h;
this.index = index;
}
}
public class Main {
/**
* 思想:借助大小优先队列每次取出最高塔和最低的塔进行操作,操作完之后再放回去
* 直至出现最大最小塔的高度差为1或者可用的移动次数用完。
*/
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();//塔的数量
int k = sc.nextInt();//最多操作次数
PriorityQueue<Tal> minque = new PriorityQueue<>(n, new Comparator<Tal>() {
@Override
public int compare(Tal o1, Tal o2) {
return o1.h - o2.h;
}
});
PriorityQueue<Tal> maxque = new PriorityQueue<>(n, new Comparator<Tal>() {
@Override
public int compare(Tal o1, Tal o2) {
return o2.h - o1.h;
}
});
Tal tal = null;
for (int i = 1; i <= n; i++) {
int t = sc.nextInt();
tal = new Tal(t, i);
minque.add(tal);
maxque.add(tal);
}
int s = 0;//最小稳定值
int times = 0;//移动次数
//记录移动的索引
int[][] move = new int[k][2];
while (times < k) {
Tal min = minque.poll();//最低的塔
Tal max = maxque.poll();//最高的塔
//如果最低塔和最高塔高度相等或者相差为1,就没必要继续了
if (max.h - min.h <= 1) {
break;
}
//最低塔高度增加1,最高塔高度减少1
min.h = min.h + 1;
max.h = max.h - 1;
move[times][0] = max.index;
move[times][1] = min.index;
minque.add(min);
maxque.add(max);
times++;
}
s = maxque.peek().h - minque.peek().h;
System.out.println(s + " " + times);
for (int i = 0; i < times; i++) {
System.out.println(move[i][0] + " " + move[i][1]);
}
}
}
#include <bits/stdc++.h>
using namespace std;
set <pair<int,int> > s;
vector<pair<int,int> > mov;
int main(){
int n,k,h;
scanf("%d%d",&n,&k);
for(int i=0;i<n;i++){
scanf("%d",&h);
s.insert({h,i+1});
}
set <pair<int,int> >::iterator it;
int ans = k;
for(int i=1;i<=k;i++){
it = s.end();
it--;
int h1 = (*s.begin()).first ,h2 = (*it).first;
if(h1 == h2) { ans = i;break;}
int pos1 =(*s.begin()).second, pos2 =(*it).second;
s.erase(*s.begin());
s.erase(*it);
s.insert({h1+1,pos1});
s.insert({h2-1,pos2});
mov.push_back({pos2,pos1});
}
it = s.end(),it--;
int h1 = (*s.begin()).first ,h2 = (*it).first;
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);
}
#include<iostream>
using namespace std;
int main(){
int n,k,tempInt;
int s;
cin>>n>>k;
int a[n][2],m[k][2];
for(int i=0;i<n;i++){
cin>>a[i][0];
a[i][1]=i+1;
}
//数据输入完毕
//计算数据输出,即不稳定度s和最小操作次数m
//最大操作次数k,每次操作必定是由最高塔移到最低塔最合算
//每次操作前后输入输出数据的类型不变
//每次操作前进行如下判断:
//如果最大值最小值两者相差小于2,此时停止操作
//否则每次操作对不稳定度的影响分为3种情况:
//1.最大值和最小值唯一,此时s-2
//2.最大值和最小值其中仅有一个不唯一,此时s-1
//3.最大值和最小值都不唯一,此时s-0
/*****************************改进算法*****************************/
//每次操作前先统计出最大值和最小值集合,然后以最大值和最小值之差作为结束操作的一个判断参数(另一个判断参数为k)
//最大值(maxSet)最小值(minSet)集合中的元素个数差,将作为s参数的更新依据,同时也是更新最大值最小值集合的依据
//min{|maxSet|,|minSet|}将作为更新m参数的依据
//****************************进一步改进*********************************
//每次计算最大最小值集合都要遍历数组将是十分耗时的,所以不妨对塔高进行排序,这在k>n时比较有用
//采用while循环,每次开始前进行判断与s参数以及m参数的更新
//****************************冒泡排序a[n][2]从小到大排序************************************
for(int i=0;i<n-1;i++){
for(int j=0;j<n-1-i;j++){
if(a[j][0]>a[j+1][0]){
tempInt=a[j][0];
a[j][0]=a[j+1][0];
a[j+1][0]=tempInt;
tempInt=a[j][1];
a[j][1]=a[j+1][1];
a[j+1][1]=tempInt;
}
}
}
//****************************进行操作以及更新s和m参数*************************************
s=0;
int minCount,maxCount,opNum;
while(s<k&&(a[n-1][0]-a[0][0])>=2){
minCount=1;
while(minCount<n&&a[minCount][0]==a[0][0])minCount++;
maxCount=1;
while(maxCount<n&&a[n-1-maxCount][0]==a[n-1][0])maxCount++;
opNum=(maxCount<minCount)?maxCount:minCount;
if(s+opNum>k)break;
//记录操作
for(int j=0;j<opNum;j++){
(a[minCount-1-j][0])++;
(a[n-maxCount+j][0])--;
m[s+j][0]=a[n-maxCount+j][1];
m[s+j][1]=a[minCount-1-j][1];
}
s+=opNum;
}
cout<<(a[n-1][0]-a[0][0])<<' '<<s<<endl;
for(int j=0;j<s;j++){
cout<<m[j][0]<<' '<<m[j][1]<<endl;
}
return 0;
}
每次从最高的塔上拿下一个立方体,放在最低的塔上。进行k次,并在容器中记录每一次调整后塔群的不稳定值和具体的移动操作。
得到k次操作的不稳定值后,找到最小值对应的索引minIndex,输出前minIndex个移动操作即可。
import java.io.*;
import java.util.*;
class Node {
int id;
int height;
public Node(int id, int height) {
this.id = id;
this.height = height;
}
}
public class Main {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
String[] params = br.readLine().split(" ");
int n = Integer.parseInt(params[0]), k = Integer.parseInt(params[1]);
String[] strs = br.readLine().split(" ");
Node[] tower = new Node[n];
for(int i = 0; i < n; i++){
int height = Integer.parseInt(strs[i]);
tower[i] = new Node(i, height);
}
int[] minmax = getMinMax(tower);
ArrayList<String> ops = new ArrayList<>();
ArrayList<Integer> unsteady = new ArrayList<>();
unsteady.add(tower[minmax[1]].height - tower[minmax[0]].height);
while(k-- > 0){
ops.add((tower[minmax[1]].id + 1) + " " + (tower[minmax[0]].id + 1));
tower[minmax[1]].height--;
tower[minmax[0]].height++;
minmax = getMinMax(tower);
unsteady.add(tower[minmax[1]].height - tower[minmax[0]].height);
}
int min = unsteady.get(0), index = 0;
for(int i = 1; i < unsteady.size(); i++){
if(unsteady.get(i) < min){
index = i;
min = unsteady.get(i);
}
}
if(index == 0){
System.out.println(min + " " + index);
}else{
System.out.println(min + " " + index);
for(int i = 0; i < index; i++){
System.out.println(ops.get(i));
}
}
}
private static int[] getMinMax(Node[] tower) {
int minIndex = 0, maxIndex = 0, min = tower[0].height, max = tower[0].height;
for(int i = 1; i < tower.length; i++){
if(tower[i].height < min){
min = tower[i].height;
minIndex = i;
}
if(tower[i].height > max){
max = tower[i].height;
maxIndex = i;
}
}
return new int[]{minIndex, maxIndex};
}
}
def solution(k, hights): count = 1 operation = [] # 存储操作步骤 unstability = max(hights) - min(hights) while unstability > 1 and count <= k: maxhight_index = hights.index(max(hights)) minhight_index = hights.index(min(hights)) hights[maxhight_index] -= 1 hights[minhight_index] += 1 count += 1 operation.append([maxhight_index+1, minhight_index+1]) maxhight = max(hights) minhight = min(hights) unstability = maxhight - minhight count -= 1 print(unstability, count) for i in operation: print(i[0], i[1]) if __name__ == '__main__': n, k = list(map(int, input().strip().split())) hights = list(map(int, input().strip().split())) solution(k, hights)
#include <bits/stdc++.h>
using namespace std;
int a[110];
int main()
{
int n,k;
scanf("%d%d",&n,&k);
for (int i=0;i<n;i++) {
scanf("%d",a+i);
}
vector<pair<int,int>> ve;
for (int i=0;i<k;i++) {
auto p=max_element(a,a+n)-a;
auto q=min_element(a,a+n)-a;
if (a[p]==a[q]) break;
--a[p];
++a[q];
ve.push_back({p+1,q+1});
}
printf("%d %d\n",*max_element(a,a+n)-*min_element(a,a+n),ve.size());
for (auto &p:ve) {
printf("%d %d\n", p.first, p.second);
}
return 0;
} //只排一次序,然后遍历k次。时间复杂度O(nlogn + k)
/*
模拟一下过程:假如塔高度分别是2, 9, 6, 3
排序:9 , 6, 3, 2
第一步:9-->2;得 8, 6, 3, 3。 begin = 0. end = 3
第二步:8-->3.得 7, 6, 3, 4. 由于4比3大,那么前移一座塔,end = 2
第三步:7-->3.得 6, 6, 4, 4。 由于4小于6,那么4之前的塔都比它之后得塔高,end还原到最后一座。end = 3
第四步:6-->4.得 5, 6, 4, 5. 由于5比6小,begin++。5比4大,end--。begin = 1, end = 2
第五步:6-->4.得 5, 5, 5, 5.退出
5次可完成,不过有可能没有5次,无论到第几次,高度差都是 begin塔高 - end塔高。
因为我们每次移动后都保证begin的塔最高,而end的塔最低
*/
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
class solution
{
public:
void GetMin(vector<pair<int, int> >& arr, int k, vector<pair<int, int> >& result)
{
if (arr.size() == 0) {
return;
}
//先插入一个pair对象保存s,m
result.push_back(make_pair(0, k));
//排序,lambda表达式,不会的也可以自己定义函数,排的是降序(升序也行,不过后面的逻辑得反过来)
sort(arr.begin(), arr.end(), [=](const pair<int, int> a, const pair<int, int> b)
{
return a.first > b.first;
});
int begin = 0;
int end = arr.size() - 1;
int times = k;
while (begin < end && times > 0) {
times--;
result.push_back(make_pair(arr[begin].second + 1, arr[end].second + 1));
arr[begin].first--;
arr[end].first++;
//如果前一座塔的高度已经小于它之后的那座塔的高度,那么begin++,下次就搬移++后的那座塔
if (arr[begin].first < arr[begin + 1].first) {
begin++;
}
//如果该座塔大于等于在它之后的塔,说明之前的塔都一样高,现在又从最开始那座塔搬移
else {
begin = 0;
}
//较低的塔跟较高的塔搬移规则是相反的,比前一座塔高则end--。否则,end = 末尾
if (arr[end].first > arr[end - 1].first) {
end--;
}
else {
end = arr.size() - 1;
}
//他们的塔的高度一致就退出。因为我们的搬移的时候保证了begin前面的塔永远比end后面的塔高
//所以begin和end两座塔高度相等,那么必然相邻或是同一座塔
if (arr[begin].first == arr[end].first) {
break;
}
}
//最后begin位与end位塔高度差就是最小的不稳定值
result[0].first = arr[begin].first - arr[end].first;
result[0].second = k - times;
return;
}
};
int main()
{
solution s;
int n;
int k;
while (cin >> n >> k) {
vector<pair<int, int> > arr(n);
for (int i = 0; i < n; ++i) {
cin >> arr[i].first;
arr[i].second = i;
}
vector<pair<int, int> > result;
s.GetMin(arr, k, result);
for (size_t i = 0; i < result.size(); ++i) {
cout << result[i].first << " " << result[i].second << endl;
}
}
return 0;
} import java.util.*;
public class Main{
//思路和很多大佬差不多:
//(1)每次用最高塔减一,最低塔加一
//(2)约束条件为最高塔与最低塔的差<=1,或者操作次数大于最大操作次数
public static void main(String[] args){
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();//输入塔的数量
int k = sc.nextInt();//最多操作的次数
int[] heightOfTa = new int[n];//每座塔的初始高度
for(int i = 0; i < n; i++){
heightOfTa[i] = sc.nextInt();
}
ArrayList<Integer> list1 = new ArrayList<Integer>();
ArrayList<Integer> list2 = new ArrayList<Integer>();
int count = 0;//操作次数
for(int i = 0; i < k; i++){
//找到最高塔所在的下标
int max = findMax(heightOfTa);
//找到最低塔所在的下标
int min = findMin(heightOfTa);
//判断是否达到约束条件:(1)最高与最低塔之间最多相差1;(2)操作次数大于最大操作次数
if(arriveGoal(heightOfTa[max], heightOfTa[min]) || count > k){
break;
}
count++;//操作次数加1
heightOfTa[max]--;//最高塔放一个立方体到最低塔,高度减一
heightOfTa[min]++;//同时最低塔得到一个立方体,高度加一
list1.add(max + 1);//存放当前操作的下标便于输出,加一是因为原始下标是从0开始
list2.add(min + 1);
}
System.out.println(heightOfTa[findMax(heightOfTa)] - heightOfTa[findMin(heightOfTa)] + " " + count);
for(int i = 0; i < list1.size(); i++){
System.out.println(list1.get(i) + list2.get(i));
}
}
//寻找最高塔所在下标
public static int findMax(int[] heightOfTa){
int max = heightOfTa[0];
int maxIndex = 0;
for(int i = 0; i < heightOfTa.length; i++){
if(max < heightOfTa[i]){
maxIndex = i;
max = heightOfTa[i];
}
}
return maxIndex;
}
//寻找最低塔所在下标
public static int findMin(int[] heightOfTa){
int min = heightOfTa[0];
int minIndex = 0;
for(int i = 0; i < heightOfTa.length; i++){
if(min > heightOfTa[i]){
minIndex = i;
min = heightOfTa[i];
}
}
return minIndex;
}
//判断是否达到目标条件
public static boolean arriveGoal(int h1, int h2){
boolean isArrive = false;
if(h1 - h2 <= 1){
isArrive = true;
}
return isArrive;
}
} import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
/**
*思路:找到数组中最大的和最小的,将最大的减一给最小的加一,这样即为一次操作,遍历 k
直至结束,或达到最稳定状态后提前退出,所以输出的 k 不一定等于给定的 k
*/
public class Main{
public static void main(String[]args){
//所有录入
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
int k = sc.nextInt();
int a[] = new int[n];
for(int i = 0; i < n; i++){
a[i] = sc.nextInt();
}
//找出最小和最大,最大的减一,最小的加一
findmin(a,n,k);
}
private static void findmin(int[] a,int n,int k){
if(a.length > 0){
int i;
// l1 发送塔,送一个立方体给 l2
List<Integer> l1 = new ArrayList<Integer>();
// l2 是接收塔,从 l1 收到一个立方体
List<Integer> l2 = new ArrayList<Integer>();
int max = 0, min = 0;
for( i = 0; i < k; i++){
max = 0;
min = 0;
for(int j = 0; j < n; j++){
if(a[j] > a[max]){
max = j;
}
if(a[j] < a[min]){
min = j;
}
}//可能在k次数内就已经达到最大稳定,可以提前结束
if(a[max] - a[min] < 1){
break;
}else{
a[max]--;
a[min]++;
//最大和最小的位置记录下来,一会输出
l1.add(max+1);
l2.add(min+1);
}
}
//以上代码最后一次执行后,最大值最小值都变了,所以重新找到最大最小值,然后输出
min=0;
max=0;
for(int m=0;m<n;m++){
if(a[m]>a[max])
{
max=m;
}
if(a[m]<a[min]){
min=m;
}
}
System.out.println((a[max]-a[min]) +" "+i);
for(int k1 = 0; k1 < l1.size(); k1++){
System.out.println(l1.get(k1)+" " + l2.get(k1));
}
}
}
} import sys n,k=list(map(int,sys.stdin.readline().split())) height=list(map(int,sys.stdin.readline().split())) res=[] for i in range(k): res.append([height.index(max(height))+1,height.index(min(height))+1]) height[height.index(max(height))]-=1 height[height.index(min(height))]+=1 print(str(max(height)-min(height))+' '+str(k)) for i in res: print(str(i[0])+' '+str(i[1]))
while True:
try:
n,k = map(int,input().split())
arr = list(map(int,input().split()))
for i in range(len(arr)):
arr[i] = [i+1,arr[i]]
arr.sort(key = lambda x:(x[1],x[0]),reverse = True)
re = []
kk = k
while 1:
if k==0 or arr[0][1]-arr[-1][1]<=1:
break
k-=1
arr[0][1]-=1
arr[-1][1]+=1
re.append([arr[0][0],arr[-1][0]])
l = 0
r = -1
while 1:
if arr[l][1]<arr[l+1][1]:
arr[l],arr[l+1] = arr[l+1],arr[l]
l+=1
else:
break
while 1:
if arr[r][1]>arr[r-1][1]:
arr[r],arr[r-1] = arr[r-1],arr[r]
r-=1
else:
break
s = abs(arr[0][1]-arr[-1][1])
k = kk-k
print(s,k)
for i in re:
print(' '.join(str(j) for j in i))
except:
break