迅雷9.25笔试

第一题

求相同数字的子序列的最大长度,允许修改3次。
转化为区间内相同数字出现最大次数与区间长度的差值小于等于3的滑动窗口。

  1. 右指针移动修改出现次数
  2. 遍历所有可能出现的次数,得到最大出现次数
  3. 移动左值针直到满足条件
  4. 维护结果
#include<bits/stdc++.h>  
using namespace std;  
int main() {  
    vector<int> nums;  
    int k;  
    while (cin >> k) {  
        nums.push_back(k);  
        if (getchar() == '\n') break;  
    }  
    //滑动窗口记录当前里面数量最多的数字  
    int n = nums.size();  
    int left = 0;  
    int h[21];  
    int res = 0;  
    memset(h, 0, sizeof(h));  
    for (int i = 0; i < n; i++) {  
        h[nums[i] + 10] += 1;  
        int tmp = 0;  
        for (int j = 0; j <= 20; j++) {  
            tmp = max(tmp, h[j]);  
        }  
        while (i - left + 1 - tmp > 3) {  
            h[nums[left] + 10] -= 1;  
            tmp = 0;  
            for (int j = 0; j <= 20; j++) {  
                tmp = max(tmp, h[j]);  
            }  
            left++;  
        }  
        res = max(res, i - left + 1);  
    }  
    cout << res;  
    return 0;  
}

第二题

两个字符串之间能否通过固定的映射进行转化
使用map模拟对应的映射,如果出现了不同的映射则失败

#include<bits/stdc++.h>  
using namespace std;  
int main() {  
    string s1,s2;  
    cin >> s1 >> s2;  
    int n1 = s1.length();  
    int n2 = s2.length();  
    if (n1 != n2) {  
        cout << "false" << endl;  
        return 0;  
    }  
    unordered_map<char,char> mp;  
    for (int i = 0; i < n1; i++) {  
        if (mp.count(s1[i])) {  
            if (mp[s1[i]] == s2[i]) continue;  
            else {  
                cout << "false" << endl;  
                return 0;  
            }  
        }  
        else {  
            mp[s1[i]] = s2[i];  
        }  
    }  
    cout << "true" << endl;  
    return 0;  
}

第三题

给出n个点的集合,每个点有对应的价值和类别。对应点集合的价值为所有点的价值之和和集合中类别数量的平方。请问获取k个点的集合的最大价值为多少

  1. 同一个点加入到集合中有两种不同的价值表示(是否为新的种类)
    1. 本身的价值
    2. 本身的价值+2 * m - 1; m为加入该点后种类的数量和;
  2. 维护两个不同的优先队列,分别维护已有种类的点和未知种类的点
  3. 每次加入点比较两个优先队列的头部,选取其中之一加入集合
  4. 需要维护优先队列的头部满足要求(未被使用和未有相同类的点加入集合)
#include<bits/stdc++.h>  
using namespace std;  
struct node{  
    int a,b,c;  
    node(int i, int j, int k) {  
        a = i;  
        b = j;  
        c = k;  
    }  
    bool operator<(const node& n) const {  
        return a < n.a;  
    }  
};  
int main() {  
    int n,k;  
    cin >> n >> k;  
    //维护两个优先队列,第一个是已有类的优先队列,另一个是假设没有对应标签的优先队列  
    priority_queue<node> pq1;  
    priority_queue<node> pq2;  
    for (int i = 0; i < n; i++) {  
        int f,s;  
        cin >> f >> s;  
        pq1.push(node(f,s, i));  
        pq2.push(node(f,s, i));  
    }  
    int h[n + 1];  
    memset(h, 0, sizeof(h));  
    int vis[n + 1];  
    memset(vis, 0, sizeof(h));  
    int surplus = k;  
    long long res = 0;  
    while (surplus > 0) {  
        surplus -= 1;  
        while ((!pq2.empty()) && (h[pq2.top().b] == 1 || vis[pq2.top().c] == 1)) {  
            pq2.pop();  
        }  
        while ((!pq1.empty()) && (vis[pq1.top().c] == 1)) {  
            pq1.pop();  
        }  
        int flag = 0;  
        int r1 = 0;  
        int r2 = 0;  
        if (!pq2.empty()) {  
            //还存在不在类中的元素  
            r2 = pq2.top().a + 2 * (k - surplus) -1;  
        }  
        if (!pq1.empty()) {  
            //还存在不在类中的元素  
            r1 = pq1.top().a;  
        }  
        if (r1 >= r2) {  
            res = res + r1;  
            vis[pq1.top().c] = 1;  
            pq1.pop();  
        }  
        else {  
            res = res + r2;  
            vis[pq2.top().c] = 1;  
            h[pq2.top().b] = 1;  
            pq2.pop();  
        }  
    }  
    cout << res;  
    return 0;  
}
posted @ 2024-09-27 17:24  tanch25  阅读(14)  评论(0)    收藏  举报