校招算法笔面试 | 校招笔面试真题-塔

题目

题目链接

题目难度:二星
考察点:贪心、模拟

方法:贪心、模拟

  1. 分析:
    我们分析一下题意,如果想尽可能的让塔的不稳定性小的话,那么就需要让最高塔高度与最低塔高度的差尽可能低,也就是让最高塔的高度尽可能低,最低塔的高度尽可能高。那么我们每次进行操作的时候就是首先将整个高度数组按照从小到大进行排序,然后高度最大值-1,高度最小值+1。一直循环k次, 在每次进行操作的时候分别记录最大值和最小值即可。还需要注意的一点是如果高度最大值-高度最小值<=1的时候,此时就不需要进行操作了,因为此时操作是完全多余的,而题目让我们求的是最少操作次数。
    举个例子:
    就拿样例来说,我们可以进行两次操作:
    第一次操作:我们首先将高度数组排序变为:
    5, 5, 8
    将高度最大值减1,最小值加1,同时记录操作数组的下标(2, 1)此时高度数组变为:
    6, 5, 7
    第二次操作:在将高度数组进行排序,得到:
    5,6,7
    然后将高度最大值减1,最小值加1,同时记录操作数组的下标(2, 3),注意此时的下标并不是排序之后的下标,是原先高度数组的下标,此时高度数组变为:
    6, 6, 6
    进行完两次操作之后,此时不稳定度达到最小,最小为0。然后输出操作数组下标:
    (2, 1)
    (2, 3)
    算法实现:
    (1). 首先用一个结构体数组保存高度值和下标。
    (2). 然后进行k次循环,在每次循环种,首先对结构体数组进行排序,排序规则按照高度值从小到大。排序之后判断高度最大值-高度最小值是否小于等于1,如果小于等于1的话就直接退出此次循环,然后输出结果。否则,将高度最大值-1,高度最小值+1,同时记录此次高度最大值和最小值的下标。
    (3). 在执行完k次循环之后,我们在输出高度最大值和最小值的差,此时的差就是不稳定度最小的。然后在根据之前保留的操作数组,输出即可。

  2. 复杂度分析:
    时间复杂度:O(k*nlog(n))
    空间复杂度:O(max(n, k))

  3. 代码:

#include <bits stdc++.h>
using namespace std;
const int MAXN = 1e2+5;
struct Node {
    int x, y;
}a[MAXN], b[MAXN*10];
bool cmp(Node A, Node B) {
    return A.x &lt; B.x;
}
int main() {
    int n, k; cin&gt;&gt;n&gt;&gt;k;
    for(int i=0; i<n; i++) { cin>&gt;a[i].x;
        a[i].y = i+1;
    }
    int cnt = 0;
    while(k--) {
        sort(a, a+n, cmp);
        if(a[n-1].x-a[0].x &lt;= 1) break;
        a[0].x++;
        a[n-1].x--;
        b[cnt].x = a[n-1].y;
        b[cnt++].y = a[0].y;
    }
    sort(a, a+n, cmp);
    cout&lt;</n;></bits>

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值