Tower--Niuke.com--Interview Questions

Title description

Xiaoyi has some cubes, each of which has a side length of 1. He used these cubes to build some towers.

Now Xiaoyi defines: the unstable value of these towers is the height difference between the tallest tower and the lowest tower among them.

Xiao Yi wanted to make these towers as stable as possible, so he did the following: each time he took a cube from one tower and put it on another tower.

Note that Xiao Yi would not put the cube on its original tower, because he thought it was meaningless.

Now Xiao Yi wants to know what the minimum instability value is after he has performed no more than k operations.

Enter description:

The two numbers in the first line n,k (1 <= n <= 100, 0 <= k <= 1000) represent the number of towers and the maximum number of operations. 
There are n numbers in the second row, ai (1 <= ai <= 104) represents the initial height of the i-th tower.

Output description:

The two numbers s, m in the first line represent the smallest unstable value and the number of operations (m <= k). The 
next m lines, two numbers x, y in each line represent the removal of a cube from the x-th tower. Go to the yth tower.

Example 1

enter

 

3 2
5 8 5

Output

 

0 2
2 1
2 3

 

Reference Code:

#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;
}

 

Guess you like

Origin blog.csdn.net/qq_40513792/article/details/104287945