9646516T4是近期做过的最难的笔试压轴题。1.给球员得分记录找mvp,按照题意模拟即可,弄个map存下分数#include <bits/stdc++.h>using namespace std;using ll = long long;const int INF = 0x3F3F3F3F;const int maxn = 2e5 + 555;const int MOD = 1e9 + 7;int32_t main() {    ios::sync_with_stdio(false);    cin.tie(0);    cout.tie(0);    cout.precision(10);    cout << fixed;    int n;    cin >> n;    string ta, tb;    cin >> ta >> tb;    map<string, int> tm;    map<string, map<string, int>> pm;    int mvp_val = -1e9;    string mvp;    for (int i = 0; i < n; i++) {        string player, team;        int val;        cin >> player >> team >> val;        tm[team] += val;        pm[team][player] += val;        if (pm[team][player] > mvp_val) {            mvp_val = pm[team][player];            mvp = player;        }    }    if (tm[ta] == tm[tb]) {        cout << "ended in a draw" << endl;    } else if (tm[ta] > tm[tb]) {        cout << ta << endl;    } else {        cout << tb << endl;    }    cout << mvp << endl;    return 0;}2.给出隐身逻辑,有草丛隐身和buff隐身两种,判断A是否能看到B。先处理下每个人物i是否在草丛j中,查询的时候先看b是否开了buff,然后看ab是否是一伙的,之后再看b是否在草丛中,如果在再看ab在不在一个草丛中。我用了bitset优化,暴力应该也可以。注意B不在草丛的情况,没注意的话会卡56%#include <bits/stdc++.h>using namespace std;using ll = long long;const int INF = 0x3F3F3F3F;const int maxn = 2e5 + 555;const int MOD = 1e9 + 7;struct user {    double x, y;    int buff, cls;    bitset<200> st;};vector<user> V;bool inside_circle(double cx, double cy, double cr, double x, double y) {    double ox = x - cx;    double oy = y - cy;    double d = ox * ox + oy * oy;    return d <= cr * cr;}bool inside_rect(double A, double B, double C) { return A <= B && B <= C; }int32_t main() {    ios::sync_with_stdio(false);    cin.tie(0);    cout.tie(0);    cout.precision(10);    cout << fixed;    int n, m, q;    cin >> n >> m >> q;    for (int i = 0; i < n; i++) {        user s;        cin >> s.x >> s.y >> s.buff >> s.cls;        V.push_back(s);    }    for (int i = 0; i < m; i++) {        int t;        cin >> t;        if (t == 0) {            double cx, cy, cr;            cin >> cx >> cy >> cr;            for (auto &u : V) {                u.st[i] = inside_circle(cx, cy, cr, u.x, u.y);            }        } else {            set<double> sx, sy;            for (int j = 0; j < 4; j++) {                double x, y;                cin >> x >> y;                sx.insert(x);                sy.insert(y);            }            assert(sx.size() == 2);            assert(sy.size() == 2);            for (auto &u : V) {                u.st[i] = inside_rect(*sx.begin(), u.x, *next(sx.begin())) &&                          inside_rect(*sy.begin(), u.y, *next(sy.begin()));            }        }    }    while (q--) {        int a, b;        cin >> a >> b;        a--;        b--;        if (V[b].buff) {            cout << 0 << endl;        } else if (V[a].cls != V[b].cls) {            if (!V[b].st.count()) {                cout << 1 << endl;            } else {                if (((V[a].st & V[b].st).count())) {                    cout << 1 << endl;                } else {                    cout << 0 << endl;                }            }        } else {            cout << 1 << endl;        }    }    return 0;}3.给一堆物品,每个物品有两个值a和b,求最多取出k个物品的条件下,取出a总和为y的物品,最小的b总和是多少。a和y有正有负,k<=5。这题数据水了,暴力DP 100ms轻松过,正解可能需要折半搜索优化下。#include <bits/stdc++.h>using namespace std;using ll = long long;const int INF = 0x3F3F3F3F;const int maxn = 2e5 + 555;const int MOD = 1e9 + 7;const char *FAIL_FLAG = "Cannot Make It!";int32_t main() {    ios::sync_with_stdio(false);    cin.tie(0);    cout.tie(0);    cout.precision(10);    cout << fixed;    int n, k, x, y;    cin >> n >> k >> x >> y;    if (x == 1)        y = -y;    vector<pair<int, int>> V;    for (int i = 0; i < n; i++) {        int v, a, b;        cin >> v >> a >> b;        if (a == 1)            b = -b;        V.push_back({b, v});    }    vector<unordered_map<int, int>> F(6);    F[0][0] = 0;    for (auto [a2, b2] : V) {        for (int i = k; i >= 0; i--) {            for (auto [a, b] : F[i - 1]) {                if (!F[i].count(a2 + a)) {                    F[i][a2 + a] = b + b2;                } else {                    F[i][a2 + a] = min(b + b2, F[i][a2 + a]);                }            }        }    }    ll ans = 1e18;    for (int i = 0; i <= k; i++) {        if (F[i].count(y)) {            ans = min(ans, 1LL * F[i][y]);        }    }    if (ans < 1e18) {        cout << ans << endl;    } else {        cout << FAIL_FLAG << endl;    }    return 0;}4.给一个字符串矩阵(n*m~1e5),每次移动可以上下左右走,也可以瞬移到相同字符处,代价都是1,给出1e5个询问,求两点最短路。这题出的真心不错,一眼就能看到思路,但是需要处理很多细节。首先先加26个辅助点,代表a-z,每个辅助点连向对应字符位置,由于辅助点要一来一回,为了方便起见,将辅助点边权设为1,普通边边权为2,求出答案后除以2.从a到b要么不使用传送,那么答案是曼哈顿距离,要么至少使用一次瞬移。此时A到B的答案为A->中间点X->辅助点->B。此时可以枚举辅助点的类型,这样辅助点->B这段距离可以预处理出来。中间点X->辅助点代价是1。A->中间点X代价是A到最近的这个类型的点的距离,这可以bfs预处理出来。#include <bits/stdc++.h>using namespace std;using ll = long long;const int INF = 0x3F3F3F3F;const int maxn = 2e5 + 555;const int MOD = 1e9 + 7;const int dx[] = {1, -1, 0, 0};const int dy[] = {0, 0, 1, -1};#define IDX(x, y) (((x) * (m)) + (y))void dijk(int s, vector<int> &D, const vector<vector<pair<int, int>>> &G) {    set<pair<int, int>> st;    st.insert({0, s});    D[s] = 0;    while (!st.empty()) {        auto [dis, pos] = *st.begin();        st.erase(st.begin());        if (D[pos] < dis) {            continue;        }        for (auto [to, cost] : G[pos]) {            if (D[to] > cost + dis) {                D[to] = cost + dis;                st.insert({D[to], to});            }        }    }}vector<int> chr[26];int n, m;void bfs(int ch, vector<int> &dis, const vector<vector<pair<int, int>>> &G) {    queue<pair<int, int>> q;    for (int i : chr[ch]) {        q.push({0, i});        dis[i] = 0;    }    while (!q.empty()) {        auto [d, idx] = q.front();        int x = idx / m;        int y = idx - x * m;        q.pop();        for (int k = 0; k < 4; k++) {            int x2 = x + dx[k];            int y2 = y + dy[k];            if (x2 >= 0 && x2 < n && y2 >= 0 && y2 < m) {                if (dis[IDX(x2, y2)] > d + 1) {                    dis[IDX(x2, y2)] = d + 1;                    q.push({d + 1, IDX(x2, y2)});                }            }        }    }}int32_t main() {    ios::sync_with_stdio(false);    cin.tie(0);    cout.tie(0);    cout.precision(10);    cout << fixed;    cin >> n >> m;    vector<string> V(n);    for (int i = 0; i < n; i++) {        cin >> V[i];    }    vector<vector<pair<int, int>>> G(n * m + 100);    for (int i = 0; i < n; i++) {        for (int j = 0; j < m; j++) {            chr[V[i][j] - 'a'].push_back(IDX(i, j));            for (int k = 0; k < 4; k++) {                int x = i + dx[k];                int y = j + dy[k];                if (x >= 0 && x < n && y >= 0 && y < m) {                    G[IDX(i, j)].push_back({IDX(x, y), 2});                }            }            G[IDX(i, j)].push_back({n * m + V[i][j] - 'a', 1});            G[n * m + V[i][j] - 'a'].push_back({IDX(i, j), 1});        }    }    vector<vector<int>> dis(26, vector<int>(n * m + 30, INF));    for (int i = 0; i < 26; i++) {        dijk(n * m + i, dis[i], G);    }    vector<vector<int>> dis2(26, vector<int>(n * m + 30, INF));    for (int i = 0; i < 26; i++) {        bfs(i, dis2[i], G);    }    int q;    cin >> q;    while (q--) {        int x0, x1, y0, y1;        cin >> x0 >> y0 >> x1 >> y1;        x0--;        x1--;        y0--;        y1--;        int ch = V[x1][y1] - 'a';        ll ans = abs(x0 - x1) + abs(y0 - y1);        for (int i = 0; i < 26; i++) {            ll step1 = dis2[i][IDX(x1, y1)] * 2;            ll step2 = 1;            ll step3 = dis[i][IDX(x0, y0)];            ll now = step1 + step2 + step3;            ans = min(ans, now / 2);        }        cout << ans << endl;    }    return 0;}
点赞 8
评论 5
全部评论

相关推荐

昨天 16:40
门头沟学院 Java
看到这一幕,本大学生心都碎了2
真的很糟糕:挖藕,让他知道什么叫便宜没好货
点赞 评论 收藏
分享
07-07 17:06
已编辑
深圳技术大学 golang
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务