题目描述
小易有一些立方体,每个立方体的边长为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座塔上。
示例1
输入
3 2 5 8 5
输出
0 2 2 1 2 3
参考代码:
#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;
}