笔试强训Day38-1.15(Leetcode)

发布于:2025-02-10 ⋅ 阅读:(22) ⋅ 点赞:(0)

天使果冻

输入:
5
1 2 5 3 5
4
2
3
4
5
输出:
1//前2个数,第二大的是1。
2//前3个数,第二大的是2。
3//前4个数,第二大的是3。
5//前5个数,第二大的是5。
错误示范:

超时,由于使用了优先队列,当x很大时,入队出队非常浪费时间。---》通过37%

优化成在内部定义优先队列,不需要出队。---》通过50%

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

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);

    int n;
    cin >> n;
    vector<int> a(n);
    for (int i = 0; i < n; ++i) {
        cin >> a[i];
    }

    int q;
    cin >> q;
    while (q--) {
        int x;
        cin >> x;
        priority_queue<int> pq;//默认最大堆,加上greater是最小堆
        for (int i = 0; i < x; ++i) {
            pq.push(a[i]);
        }
        pq.pop(); // 移除最大的元素
        cout << pq.top() << '\n'; // 输出第二大的元素
    }

    return 0;
}
思路:
  • 使用两个数组 max1 和 max2 分别存储前 i 个元素的最大值和次大值。

  • 在遍历时动态更新最大值和次大值。

正确代码:
#include <iostream>
#include <vector>
using namespace std;

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);

    int n;
    cin >> n;
    vector<int> a(n);
    for (int i = 0; i < n; ++i) {
        cin >> a[i];
    }

    // 预处理每个位置的最大值和次大值
    vector<int> max1(n), max2(n);
    max1[0] = a[0];
    max2[0] = -1; // 没有次大值
    for (int i = 1; i < n; ++i) {
        if (a[i] > max1[i - 1]) {
            max2[i] = max1[i - 1];
            max1[i] = a[i];
        } else if (a[i] == max1[i - 1]) {
            max1[i] = a[i];
            max2[i] = a[i];
        } else {
            max1[i] = max1[i - 1];
            max2[i] = max(max2[i - 1], a[i]);
        }
    }

    int q;
    cin >> q;
    while (q--) {
        int x;
        cin >> x;
        cout << max2[x - 1] << '\n';
    }

    return 0;
}

dd爱旋转

输入输出样例:

思路;
  • 旋转 180° 等价于将矩阵上下翻转后再左右翻转。

  • 行镜像操作就是简单的上下翻转。

  • 异或运算:相同为零,不同为一。

代码:

~~~这种思路很好~~~:

该代码中,state有四种状态00、01、10、11。

初始状态=当前状态:异或为零,回到原始状态。

初始状态!=当前状态:异或之后可以保存这两种状态。

01^10=11,00^01=01,00^10=10,11^01=10,11^10=01……经过验证正确!

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

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);

    int n;
    cin >> n;
    vector<vector<int>> matrix(n, vector<int>(n));
    for (int i = 0; i < n; ++i) {
        for (int j = 0; j < n; ++j) {
            cin >> matrix[i][j];
        }
    }

    int q;
    cin >> q;
    int state = 0; // 0: 原始状态, 1: 旋转180°, 2: 行镜像, 3: 旋转180° + 行镜像
    while (q--) {
        int x;
        cin >> x;
        if (x == 1) {
            state ^= 1; // 切换旋转180°状态
        } else if (x == 2) {
            state ^= 2; // 切换行镜像状态
        }
    }

    // 根据最终状态输出矩阵
    if (state == 0) {
        // 原始状态
        for (int i = 0; i < n; ++i) {
            for (int j = 0; j < n; ++j) {
                cout << matrix[i][j] << " ";
            }
            cout << "\n";
        }
    } else if (state == 1) {
        // 旋转180°
        for (int i = n - 1; i >= 0; --i) {
            for (int j = n - 1; j >= 0; --j) {
                cout << matrix[i][j] << " ";
            }
            cout << "\n";
        }
    } else if (state == 2) {
        // 行镜像
        for (int i = n - 1; i >= 0; --i) {
            for (int j = 0; j < n; ++j) {
                cout << matrix[i][j] << " ";
            }
            cout << "\n";
        }
    } else if (state == 3) {
        // 旋转180° + 行镜像
        for (int i = 0; i < n; ++i) {
            for (int j = n - 1; j >= 0; --j) {
                cout << matrix[i][j] << " ";
            }
            cout << "\n";
        }
    }

    return 0;
}

小红取数

输入:
5 5
4 8 2 9 1
输出:
20//取后四个数即可
代码:

dp的思想。

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

const long long INF = LLONG_MIN;

int main() {
    int n, k;
    cin >> n >> k;
    vector<long long> a(n);
    for (int i = 0; i < n; ++i) {
        cin >> a[i];
    }

    // dp[i][j] 表示前 i 个数中,和模 k 等于 j 的最大和
    vector<vector<long long>> dp(n + 1, vector<long long>(k, INF));
    dp[0][0] = 0;

    for (int i = 1; i <= n; i++) {
        for (int j = 0; j < k;j++) 
        { 
            // 更新当前数带来的对所有余数的影响:
            // dp[i][(j+arr[i-1])%k]更新对余数的影响,选最大值:
            // 要么加入arr[i-1]:选择余数为j的状态加上arr[i-1],则对新余数(j+arr[i-1])%k产生影响,更新
            // 要么不加入arr[i-1], 选择前一个状态本来余数就是(j+arr[i-1])%k的值
            dp[i][(j + a[i - 1]) % k] = max(dp[i - 1][j] + a[i - 1],dp[i - 1][(j + a[i - 1]) % k]);
        }
    }

    if (dp[n][0] <= 0) {
        cout << -1 << endl;
    } else {
        cout << dp[n][0] << endl;
    }

    return 0;
}


网站公告

今日签到

点亮在社区的每一天
去签到