Tower - Niuke.com - Preguntas de la entrevista

Descripción del Título

Xiaoyi tiene algunos cubos, cada uno de los cuales tiene una longitud de lado de 1. Usó estos cubos para construir algunas torres.

Ahora Xiaoyi define: el valor inestable de estas torres es la diferencia de altura entre la torre más alta y la torre más baja entre ellas.

Xiao Yi quería que estas torres fueran lo más estables posible, así que hizo lo siguiente: cada vez que tomaba un cubo de una torre y lo colocaba en otra torre.

Tenga en cuenta que Xiao Yi no pondría el cubo en su torre original, porque pensó que no tenía sentido.

Ahora Xiao Yi quiere saber cuál es el valor mínimo de inestabilidad después de que no haya realizado más de k operaciones.

Ingrese descripción:

Los dos números de la primera línea n, k (1 <= n <= 100, 0 <= k <= 1000) representan el número de torres y el número máximo de operaciones. 
Hay n números en la segunda fila, ai (1 <= ai <= 104) representa la altura inicial de la i-ésima torre.

Descripción de salida:

Los dos números s, m en la primera línea representan el valor inestable más pequeño y el número de operaciones (m <= k). Las 
siguientes m líneas, dos números x, y en cada línea representan la eliminación de un cubo de la x- a torre. Ve a la y-ésima torre.

Ejemplo 1

ingresar

 

3 2 
5 8 5

Producción

 

0 2 
2 1 
2 3

 

Código de referencia:

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

 

Supongo que te gusta

Origin blog.csdn.net/qq_40513792/article/details/104287945
Recomendado
Clasificación