记录2022.9.4网易笔试

130 阅读1分钟

1

image.png

image.png

#include <iostream>
#include <vector>
#include <unordered_map>
#include <algorithm>
using namespace std;

int main()
{
    int n, k;
    cin >> n;
    cin >> k;
    vector<int> v(n, 0);
    unordered_map<int, int> m;
    int maxElement = 0;
    for (int i = 0; i < n; ++i)
    {
        cin >> v[i];
        m[v[i]%k]++;
        maxElement = max(maxElement, m[v[i]%k]);
    }
    cout << maxElement;
    return 0;
}

2

image.png

image.png

image.png

解题思路:k个1最多组成k-1对相邻1(连续k个1),最少则是k-1-(n-k),t在这个范围之内可以通过把0依次插入连续的1之间来构造得到(每插入一个0减少一个相邻对)

代码

#include <iostream>
#include <vector>
using namespace std;

int main() {
    int n, k, t;
    cin >> n >> k >> t;
    // 相邻 1 max: k-1 min: k-1-(n-k)
    if (t <= k-1 && k <= n && k-1- (n-k) <= t){
        string s = "";
        int p = k - 1 - t; // 插入 10
        while(p--){
            s += "10";
        }
        p = k - (k-1-t); // 插入剩下的 1
        while(p--){s += "1";}
        p = n - k - (k-1-t); // 还有 0 则继续插入
        while(p--){s += "0";}
        cout << s;
    }
    else cout << -1;
}

说明:可以通过下面的例子理解

n = 6, k = 4 时

相邻 1 max:k-1 = 3 min: k-1-(n-k)=1

①t = 3 时,插入10: k-1-t=0 个

接着插入剩下的1: k-(k-1-t)=4个

继续插入剩下的0: n-k-(k-1-t)=2个

最终得到:111100

②t = 1 时同理,最终得到:101011

3

image.png

image.png

解题思路:先确定一个解的范围,然后通过二分+验证来找到解。需要注意的是验证答案的时候把k刚好用完不一定是最优解,应该按照剩下的k>=0算合法解来逼近最优解

代码

#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

typedef long long ll;
ll a[1000];
int n;
ll k, x;
bool check(ll target)
{
    ll tmp = k;
    for (int i = 0; i < n; ++i)
    {
        tmp -= max(0LL, ((a[i] - target) + x - 1) / x);
        if (tmp < 0)
            return false;
    }
    if (tmp >= 0)
        return true;
    return false;
}

int main()
{

    cin >> n >> k >> x;
    ll maxx = 0;
    for (int i = 0; i < n; ++i)
    {
        cin >> a[i];
        maxx = max(a[i], maxx);
    }

    ll l = maxx - k * x, r = maxx;
    ll mid;
    while (l <= r)
    {
        mid = (l + r) >> 1;
        if (check(mid))
        {
            r = mid - 1;
        }
        else
            l = mid + 1;
    }
    cout << l;
}

要点:(a[i] - target) + x - 1) / x 是把所有数字减到小于等于b所需要的最小操作次数

补充一道类似的题

给定一个数组 a,包含 n 个整数

再给定一个整数 k,可以给数组中任意整数加 1,总共可以加 k 次

加完 k 次后,找到数组中的最大值。最后要求得一个最小的最大值

题解:找出数组中最大的那个数p,求出数组中所有数与p的差值之和m 如果差值之和大于等于k,则最后最大值为p 否则为 ceil((k-m)/n)+p

作者:苏州小朋友 链接:leetcode.cn/circle/disc… 来源:力扣(LeetCode) 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

4

image.png

image.png