2025 睿抗机器人开发者大赛CAIP-编程技能赛-本科组(省赛)题解

目录

前言

RC-u1 早鸟价

考察算法:

思路:

注意点:

ac code:

RC-u2 谁进线下了?III

考察算法:

思路:

注意点:

ac code:

RC-u3 点格棋

评价:

考察算法:

思路:

注意点:

ac code:

RC-u4 Tree Tree 的

考察算法:

思路:

注意点:

ac code:

RC-u5 游戏设计师

考察算法:

思路:

注意点:

ac code:


前言

被t3折磨坏了,几乎全部时间都在调t3,最后只拿了36分,呜呜呜

RC-u1 早鸟价

考察算法:

        模拟。

思路:

        无。

注意点:

        无。

ac code:

void solve()
{
    int n;
    cin >> n;
    while (n--)
    {
        int m, d, c;
        cin >> m >> d >> c;

        if (m > 7 || (m == 7 && d > 11))
            cout << "Too late!" << endl;
        else
        {
            if (m < 6 || (m == 6 && d <= 20))
            {
                if (c == 1800)
                    cout << "Ok!" << endl;
                else if (c < 1800)
                    cout << "Need more!" << endl;
                else
                    cout << "^_^" << endl;
            }
            else
            {
                if (c == 2000)
                    cout << "Ok!" << endl;
                else if (c < 2000)
                    cout << "Need more!" << endl;
                else
                    cout << "^_^" << endl;
            }
        }
    }
}

RC-u2 谁进线下了?III

考察算法:

        模拟。

思路:

        无。

注意点:

        取成绩那里要上取整。

ac code:

void solve()
{
    int n, s;
    cin >> n >> s;

    ll sum = 0;
    ll cnt = 0;
    for (int i = 0; i < n; ++i)
    {
        int r, c;
        cin >> r >> c;
        sum += c;
        if (r == 1)
            ++cnt;
    }

    n = ceil((double)n / 2.0);
    if (cnt >= n)
        cout << 1 << ' ';
    else
        cout << 0 << ' ';

    if (sum >= s + 50)
        cout << 1 << endl;
    else
        cout << 0 << endl;
}

RC-u3 点格棋

评价:

        第一次做这么屎的大模拟,谁家好人初始给的点就可能越界啊。

考察算法:

        超级无敌谢特大模拟。

思路:

        判断有没有边存不存在的话,可以开四维数组或者压维后开二维数组、pair存储点开二维。

注意点:

  1. 初始给的点就可能越界
  2. 点的曼哈顿距离可能不是1
  3. 可能给出重边
  4. 下棋人错误
  5. 一次可能构造出两个正方形

ac code:

void solve()
{
    int n, m, s;
    cin >> n >> m >> s;

    auto get = [&](ll x, ll y) -> ll
    {
        return (x - 1) * m + (y - 1);
    };

    vector ans;
    ll cnt[2] = {0, 0};
    map st;
    int dx[] = {1, -1};
    auto check = [&](ll x1, ll y1, ll x2, ll y2) -> int
    {
        ll ans = 0;
        ll a = get(x1, y1);
        ll b = get(x2, y2);
        if (x1 == x2)
        {
            for (int i = 0; i < 2; ++i)
            {
                ll ca = x1 + dx[i];
                ll da = x2 + dx[i];
                ll c = get(x1 + dx[i], y1);
                ll d = get(x2 + dx[i], y2);

                if (ca > n || ca < 1 || da > n || da < 1)
                    continue;
                if (st[{a, c}] && st[{b, d}] && st[{c, d}])
                    ++ans;
            }
        }
        else if (y1 == y2)
        {
            for (int i = 0; i < 2; ++i)
            {
                ll cb = y1 + dx[i];
                ll db = y2 + dx[i];
                ll c = get(x1, y1 + dx[i]);
                ll d = get(x2, y2 + dx[i]);

                if (cb > m || db > m || cb < 1 || db < 1)
                    continue;
                if (st[{a, c}] && st[{b, d}] && st[{c, d}])
                    ++ans;
            }
        }
        return ans;
    };

    int last = 0;
    for (int i = 0; i < s; ++i)
    {
        int op, x1, x2, y1, y2;
        cin >> op >> x1 >> y1 >> x2 >> y2;

        int d = abs(x2 - x1) + abs(y2 - y1);
        int u = get(x1, y1), v = get(x2, y2);
        if (x1 < 1 || x1 > n || x2 < 1 || x2 > n || y1 < 1 || y1 > m || y2 < 1 || y2 > m)
            ans.push_back(i + 1);
        else if (d != 1)
            ans.push_back(i + 1);
        else if (op != last)
            ans.push_back(i + 1);
        else if (st[{u, v}] || st[{v, u}])
            ans.push_back(i + 1);
        else if (x1 == x2 && y1 == y2)
            ans.push_back(i + 1);
        else if (x1 != x2 && y1 != y2)
            ans.push_back(i + 1);
        else
        {
            int score = check(x1, y1, x2, y2);
            if (score)
            {
                cnt[op] += score;
                last = op;
            }
            else
                last = 1 - op;

            st[{u, v}] = st[{v, u}] = 1;
        }
    }

    if (ans.empty())
        cout << -1 << endl;
    else
    {
        for (int i = 0; i < ans.size(); ++i)
        {
            if (i < ans.size() - 1)
                cout << ans[i] << ' ';
            else
                cout << ans[i] << endl;
        }
    }
    if (cnt[0] > cnt[1])
        cout << 0 << ' ' << cnt[0] << endl;
    else
        cout << 1 << ' ' << cnt[1] << endl;
}

RC-u4 Tree Tree 的

考察算法:

        图论、树、搜索、环、并查集、暴力枚举。

思路:

        找原来就连通,在删去任意一个节点以后任然连通并且是颗树的图,由于要删去任意一个节点,所以图只能是个环或者一个节点数小于等于两个点的链。

        暴力从每个点开始dfs找环即可,同时记录前二大的环。

        找环思路:dfs记录当前节点、环中点的数量、开始节点,如果dfs到开始节点就说明是环,更新前二大的环。

注意点:

  1. 如果有一条边,最大的图(ans1)最小就有两个点
  2. 如果最大的图有超过两个点,就说明第二大的图最少有两个点
  3. 如果最大的图只有两个点,就说明第二大的图只有1个点
  4. 如果最大的图只有一个点,就说明第二大的图没有点

ac code:

void solve()
{
    int n, m;
    cin >> n >> m;
    vector g[n + 10];
    for (int i = 0; i < m; ++i)
    {
        int u, v;
        cin >> u >> v;
        g[u].push_back(v);
        g[v].push_back(u);
    }

    ll ans1 = 1, ans2 = 0;
    vector st(n + 10, 0);
    function dfs = [&](int u, int cnt, int begin) -> void
    {
        for (auto v : g[u])
        {
            if (st[v])
                continue;
            if (v == begin)
            {
                if (cnt > ans1)
                {
                    ans2 = ans1;
                    ans1 = cnt;
                }
                else if (ans2 < cnt && ans1 > cnt)
                    ans2 = cnt;
            }
            st[v] = 1;
            dfs(v, cnt + 1, begin);
            st[v] = 0;
        }
    };

    for (int i = 1; i <= n; ++i)
        dfs(i, 1, i);

    cout << ans1 << ' ' << ans2 << endl;
}

RC-u5 游戏设计师

考察算法:

        BFS、最短路、模拟。

思路:

        从终点开始反向BFS,使用三维距离数组存储每种状态到达每个点的最少步数即可。

注意点:

        每种状态翻转时很容易写错。

ac code:

void solve()
{
    int n, m, q;
    cin >> n >> m;
    vector g(n + 10);
    for (int i = 0; i < n; ++i)
        cin >> g[i];

    int start_x, start_y;
    for (int i = 0; i < n; ++i)
    {
        for (int j = 0; j < m; ++j)
        {
            if (g[i][j] == '3')
            {
                start_x = i;
                start_y = j;
                break;
            }
        }
    }

    auto check = [&](int x, int y) -> bool
    {
        return x >= 0 && x < n && y >= 0 && y < m && g[x][y] != '0';
    };

    vector>> dist(n + 10, vector>(m + 10, vector(3, MAX)));
    auto bfs = [&]() -> void
    {
        queue> q;

        q.push({start_x, start_y, 0, 0});
        dist[start_x][start_y][0] = 0;

        while (q.size())
        {
            auto [x, y, state, cnt] = q.front();
            q.pop();

            if (state == 0)
            {
                if (check(x - 1, y) && check(x - 2, y) && dist[x - 2][y][2] == MAX)
                {
                    dist[x - 2][y][2] = cnt + 1;
                    q.push({x - 2, y, 2, cnt + 1});
                }
                if (check(x + 1, y) && check(x + 2, y) && dist[x + 1][y][2] == MAX)
                {
                    dist[x + 1][y][2] = cnt + 1;
                    q.push({x + 1, y, 2, cnt + 1});
                }
                if (check(x, y - 1) && check(x, y - 2) && dist[x][y - 2][1] == MAX)
                {
                    dist[x][y - 2][1] = cnt + 1;
                    q.push({x, y - 2, 1, cnt + 1});
                }
                if (check(x, y + 1) && check(x, y + 2) && dist[x][y + 1][1] == MAX)
                {
                    dist[x][y + 1][1] = cnt + 1;
                    q.push({x, y + 1, 1, cnt + 1});
                }
            }
            else if (state == 1)
            {
                if (check(x - 1, y) && check(x - 1, y + 1) && dist[x - 1][y][1] == MAX)
                {
                    dist[x - 1][y][1] = cnt + 1;
                    q.push({x - 1, y, 1, cnt + 1});
                }
                if (check(x + 1, y) && check(x + 1, y + 1) && dist[x + 1][y][1] == MAX)
                {
                    dist[x + 1][y][1] = cnt + 1;
                    q.push({x + 1, y, 1, cnt + 1});
                }
                if (check(x, y - 1) && g[x][y - 1] != '2' && dist[x][y - 1][0] == MAX)
                {
                    dist[x][y - 1][0] = cnt + 1;
                    q.push({x, y - 1, 0, cnt + 1});
                }
                if (check(x, y + 2) && g[x][y + 2] != '2' && dist[x][y + 2][0] == MAX)
                {
                    dist[x][y + 2][0] = cnt + 1;
                    q.push({x, y + 2, 0, cnt + 1});
                }
            }
            else
            {
                if (check(x - 1, y) && g[x - 1][y] != '2' && dist[x - 1][y][0] == MAX)
                {
                    dist[x - 1][y][0] = cnt + 1;
                    q.push({x - 1, y, 0, cnt + 1});
                }
                if (check(x + 2, y) && g[x + 2][y] != '2' && dist[x + 2][y][0] == MAX)
                {
                    dist[x + 2][y][0] = cnt + 1;
                    q.push({x + 2, y, 0, cnt + 1});
                }
                if (check(x, y - 1) && check(x + 1, y - 1) && dist[x][y - 1][2] == MAX)
                {
                    dist[x][y - 1][2] = cnt + 1;
                    q.push({x, y - 1, 2, cnt + 1});
                }
                if (check(x, y + 1) && check(x + 1, y + 1) && dist[x][y + 1][2] == MAX)
                {
                    dist[x][y + 1][2] = cnt + 1;
                    q.push({x, y + 1, 2, cnt + 1});
                }
            }
        }
    };

    bfs();

    cin >> q;
    while (q--)
    {
        int sx, sy, state;
        cin >> sx >> sy >> state;

        --sx, --sy;

        bool flag = 0;
        if (state == 0)
            flag = check(sx, sy) && g[sx][sy] != '2';
        else if (state == 1)
            flag = check(sx, sy) && check(sx, sy + 1);
        else
            flag = check(sx, sy) && check(sx + 1, sy);

        if (!flag || dist[sx][sy][state] == MAX)
            cout << -1 << endl;
        else
            cout << dist[sx][sy][state] << endl;
    }
}

你可能感兴趣的:(睿抗,算法,c++)