AtCoder Weekday Contest 0025 Beta题解(AWC 0025 Beta A-E)

A - Passing Score

【题目来源】

AtCoder:A - Passing Score

【题目描述】

Takahashi is tallying the results of his school's final exam.
高桥正在统计学校的期末考试结果。

There are \(N\) students in the class, and student \(i\) scored \(A_i\) points. All scores are integers between \(0\) and \(100\), inclusive.
班级中有 \(N\) 名学生,学生 \(i\) 的得分为 \(A_i\) 分。所有分数均为 \(0\)\(100\) 之间(包含端点)的整数。

The teacher has set a passing grade of \(X\) points. Students who scored \(X\) points or more pass, while students who scored less than \(X\) points fail and must attend supplementary lessons.
老师设定了及格分数线为 \(X\) 分。得分不低于 \(X\) 分的学生通过考试,得分低于 \(X\) 分的学生未通过,必须参加补习。

Find the number of students who must attend supplementary lessons, that is, the number of students who scored less than \(X\) points.
求必须参加补习的学生人数,即得分低于 \(X\) 分的学生人数。

【输入】

\(N\) \(X\)
\(A_1\) \(A_2\) \(\ldots\) \(A_N\)

  • The first line contains an integer \(N\) representing the number of students and an integer \(X\) representing the passing grade, separated by a space.
  • The second line contains integers \(A_1, A_2, \ldots, A_N\) representing each student's score, separated by spaces.
  • \(A_i\) represents the score of student \(i\).

【输出】

Print the number of students who scored less than \(X\) points, on a single line.

【输入样例】

5 60
72 45 60 38 85

【输出样例】

2

【代码详解】

#include <bits/stdc++.h>
using namespace std;

int n, x, ans;

int main()
{
    cin >> n >> x;
    for (int i = 1; i <= n; i++)
    {
        int a;
        cin >> a;
        // 统计比 x 小的数字个数
        if (a < x)
        {
            ans++;
        }
    }
    cout << ans << endl;
    return 0;
}

【运行结果】

5 60
72 45 60 38 85
2

B - Warehouse Inspection Robot

【题目来源】

AtCoder:B - Warehouse Inspection Robot

【题目描述】

Takahashi manages a warehouse in the form of a grid with \(H\) rows and \(W\) columns. The cell at the \(i\)-th row from the top \((1 \leq i \leq H)\) and the \(j\)-th column from the left \((1 \leq j \leq W)\) is denoted as cell \((i, j)\). Each cell either has a package placed on it or is empty. The state of the warehouse is represented by \(H\) strings \(S_1, S_2, \ldots, S_H\), each of length \(W\). If the \(j\)-th character of \(S_i\) is #, then cell \((i, j)\) has a package; if it is ., the cell is empty.
高桥管理着一个 \(H\)\(W\) 列的网格仓库。从上往下数第 \(i\) 行(\(1 \leq i \leq H\))、从左往右数第 \(j\) 列(\(1 \leq j \leq W\))的单元格记为单元格 \((i, j)\)。每个单元格上要么放有一个包裹,要么为空。仓库的状态由 \(H\) 个长度为 \(W\) 的字符串 \(S_1, S_2, \ldots, S_H\) 表示。如果 \(S_i\) 的第 \(j\) 个字符是 #,则单元格 \((i, j)\) 有包裹;如果是 .,则该单元格为空。

Takahashi plans to introduce one inspection robot into this warehouse and have it collect packages by moving around. The robot is initially placed at cell \((1, 1)\) (the top-left corner).
高桥计划向仓库引入一个巡检机器人,并让它通过移动来收集包裹。机器人初始放置在单元格 \((1, 1)\)(左上角)。

The robot is given \(N\) instructions in order, represented by a string \(T\) of length \(N\). The \(k\)-th character of \(T\) \((1 \leq k \leq N)\) corresponds to the \(k\)-th instruction, and each instruction is one of the following:
机器人按顺序收到 \(N\) 条指令,由一个长度为 \(N\) 的字符串 \(T\) 表示。\(T\) 的第 \(k\) 个字符(\(1 \leq k \leq N\))对应第 \(k\) 条指令,每条指令是以下之一:

  • U: Move one cell up (row number decreases by \(1\))
    U:向上移动一个单元格(行号减少 \(1\)
  • D: Move one cell down (row number increases by \(1\))
    D:向下移动一个单元格(行号增加 \(1\)
  • L: Move one cell left (column number decreases by \(1\))
    L:向左移动一个单元格(列号减少 \(1\)
  • R: Move one cell right (column number increases by \(1\))
    R:向右移动一个单元格(列号增加 \(1\)

However, if the destination of an instruction would be outside the grid, that instruction is ignored, and the robot stays in its current position.
但是,如果指令的目的地在网格外,则该指令被忽略,机器人停留在当前位置。

The robot operates as follows:
机器人按以下方式操作:

  1. The robot is placed at cell \((1, 1)\). If cell \((1, 1)\) has a package, it is collected (the package is removed from that cell).
    机器人放置在单元格 \((1, 1)\)。如果单元格 \((1, 1)\) 有包裹,则收集该包裹(包裹从该单元格移除)。
  2. For \(k = 1, 2, \ldots, N\) in order, the \(k\)-th instruction is executed. After processing each instruction (whether the robot moved or the instruction was ignored and the robot stayed in place), if there is a package on the cell where the robot is located, it is collected (the package is removed from that cell).
    按顺序对 \(k = 1, 2, \ldots, N\) 执行第 \(k\) 条指令。在处理完每条指令后(无论机器人是否移动,或指令被忽略而机器人停留在原地),如果机器人所在的单元格有包裹,则收集该包裹(包裹从该单元格移除)。

If the robot revisits a cell from which a package has already been collected, nothing happens.
如果机器人重新访问一个已经收集过包裹的单元格,不会发生任何事情。

Determine the number of packages remaining in the warehouse after all instructions have been executed.
确定所有指令执行完毕后,仓库中剩余的包裹数量。

【输入】

\(H\) \(W\) \(N\)
\(S_1\)
\(S_2\)
\(\vdots\)
\(S_H\)
\(T\)

  • The first line contains the number of rows \(H\), the number of columns \(W\), and the number of instructions \(N\), separated by spaces.
  • The \(2\)-nd through \((H + 1)\)-th lines contain the strings \(S_i\) \((1 \leq i \leq H)\) representing the state of the warehouse.
  • \(S_i\) is a string of length \(W\), where the \(j\)-th character being # means cell \((i, j)\) has a package, and . means it is empty.
  • The \((H + 2)\)-th line contains the string \(T\) of length \(N\) representing the instructions to the robot.
  • \(T\) consists only of U, D, L, R.

【输出】

Print the number of packages remaining in the warehouse after all instructions have been executed, on a single line.

【输入样例】

3 4 9
#..#
.##.
..#.
RRDDLUUUL

【输出样例】

1

【代码详解】

#include <bits/stdc++.h>
using namespace std;
const int N = 505, M = 200005;

char g[N][N];  // 地图
int h, w, n, ans;
string s;  // 指令序列
int a[M];

int main()
{
    cin >> h >> w >> n;
    // 读取地图
    for (int i = 1; i <= h; i++)
    {
        for (int j = 1; j <= w; j++)
        {
            cin >> g[i][j];
        }
    }
    cin >> s;
    
    int x = 1, y = 1;  // 当前位置
    // 如果起点是障碍物,清除它
    if (g[x][y] == '#')
    {
        g[x][y] = '.';
    }
    
    // 处理每个指令
    for (int i = 0; i < n; i++)
    {
        if (s[i] == 'U')
        {
            int nx = x - 1, ny = y;
            // 检查移动是否超出边界
            if (nx < 1 || nx > h || ny < 1 || ny > w)
            {
                continue;
            }
            x = nx, y = ny;
            // 如果新位置是障碍物,清除它
            if (g[x][y] == '#')
            {
                g[x][y] = '.';
            }
        }
        else if (s[i] == 'D')
        {
            int nx = x + 1, ny = y;
            if (nx < 1 || nx > h || ny < 1 || ny > w)
            {
                continue;
            }
            x = nx, y = ny;
            if (g[x][y] == '#')
            {
                g[x][y] = '.';
            }
        }
        else if (s[i] == 'L')
        {
            int nx = x, ny = y - 1;
            if (nx < 1 || nx > h || ny < 1 || ny > w)
            {
                continue;
            }
            x = nx, y = ny;
            if (g[x][y] == '#')
            {
                g[x][y] = '.';
            }
        }
        else
        {
            int nx = x, ny = y + 1;
            if (nx < 1 || nx > h || ny < 1 || ny > w)
            {
                continue;
            }
            x = nx, y = ny;
            if (g[x][y] == '#')
            {
                g[x][y] = '.';
            }
        }
    }
    
    // 统计剩余障碍物数量
    for (int i = 1; i <= h; i++)
    {
        for (int j = 1; j <= w; j++)
        {
            if (g[i][j] == '#')
            {
                ans++;
            }
        }
    }
    cout << ans << endl;
    return 0;
}

【运行结果】

3 4 9
#..#
.##.
..#.
RRDDLUUUL
1

C - Air Conditioning Installation in Classrooms

【题目来源】

AtCoder:C - Air Conditioning Installation in Classrooms

【题目描述】

Takahashi is in charge of facility management at a school. The school has \(N\) classrooms, and each classroom \(i\) (\(1 \leq i \leq N\)) has one old air conditioner installed. Each classroom's air conditioner has a deterioration level \(D_i\), where a higher deterioration level means the air conditioner is older and has worse performance.
高桥负责学校的设施管理。学校有 \(N\) 间教室,每间教室 \(i\)\(1 \leq i \leq N\))安装了一台旧的空调。每间教室的空调有一个劣化程度 \(D_i\),劣化程度越高表示空调越旧、性能越差。

This time, \(M\) new air conditioners have arrived. Takahashi can choose \(0\) or more and \(M\) or fewer distinct classrooms from the \(N\) classrooms, and replace the old air conditioner in each chosen classroom with one new air conditioner. Each classroom can be replaced at most once, and it is not necessary to use all \(M\) new air conditioners. The deterioration level of a classroom where a replacement was made becomes \(0\), while the deterioration level of a classroom where no replacement was made remains at its original value \(D_i\).
这次,学校新到了 \(M\) 台新空调。高桥可以从 \(N\) 间教室中选择 \(0\)\(M\) 间不同的教室,将每间选中教室的旧空调更换为一台新空调。每间教室最多更换一次,且不必用完所有 \(M\) 台新空调。更换过的教室的劣化程度变为 \(0\),而未更换的教室的劣化程度保持其原始值 \(D_i\)

Takahashi wants to choose the classrooms for replacement wisely so as to minimize the maximum deterioration level among all classrooms after the replacements. Find the minimum achievable value of this maximum.
高桥希望通过明智地选择更换的教室,使得更换后所有教室的最大劣化程度最小化。求这个最大劣化程度的最小可能值。

【输入】

\(N\) \(M\)
\(D_1\) \(D_2\) \(\ldots\) \(D_N\)

  • The first line contains an integer \(N\) representing the number of classrooms and an integer \(M\) representing the number of new air conditioners that arrived, separated by a space.
  • The second line contains integers \(D_1, D_2, \ldots, D_N\) representing the deterioration level of each classroom, separated by spaces.

【输出】

Print in one line the minimum achievable value of the maximum deterioration level among all classrooms after the replacements.

【输入样例】

5 2
3 1 4 1 5

【输出样例】

3

【代码详解】

#include <bits/stdc++.h>
using namespace std;
const int N = 200005;

int n, m;
int d[N];  // 存储每个人的得分

int main()
{
    cin >> n >> m;
    for (int i = 1; i <= n; i++)
    {
        cin >> d[i];
    }
    // 从大到小排序
    sort(d + 1, d + n + 1, greater<int>());
    // 输出第(m+1)高的分数
    cout << d[1 + m] << endl;
    return 0;
}

【运行结果】

5 2
3 1 4 1 5
3

D - Constellation Observation Tour

【题目来源】

AtCoder:D - Constellation Observation Tour

【题目描述】

Takahashi is guiding a constellation observation tour at an observatory.
高桥正在天文台带领一个星座观测之旅。

On the observation deck of the observatory, \(N\) telescopes are installed along a number line. Each telescope is numbered from \(1\) to \(N\), and telescope \(i\) is installed at coordinate \(X_i\). No two telescopes are installed at the same coordinate.
在天文台的观测台上,沿一条数线安装了 \(N\) 台望远镜。每台望远镜编号从 \(1\)\(N\),望远镜 \(i\) 安装在坐标 \(X_i\) 处。没有两台望远镜安装在同一坐标。

During the tour, participants start in front of telescope \(S\). After that, they repeat the following movement \(Q\) times:
在观测之旅中,参与者从望远镜 \(S\) 前开始。之后,他们重复以下移动 \(Q\) 次:

  • Among the \(N-1\) telescopes excluding the one you are currently at, move to the telescope whose distance (absolute difference of coordinates) from your current position is the smallest. If there are multiple telescopes with the smallest distance, move to the one with the smallest number among them.
    \(N-1\) 台望远镜中(不包括当前所在的望远镜),移动到与当前位置距离(坐标的绝对差)最小的望远镜。如果有多个望远镜具有相同的最小距离,则移动到其中编号最小的那台。

Note that returning to the telescope you were at immediately before is not prohibited (only the telescope you are currently at is excluded from the movement candidates).
注意,不禁止返回到刚刚所在过的望远镜(只有当前所在的望远镜从移动候选中被排除)。

Determine the number of the telescope where the participant is after \(Q\) moves.
确定 \(Q\) 次移动后参与者所在的望远镜编号。

【输入】

\(N\) \(S\) \(Q\)
\(X_1\) \(X_2\) \(\cdots\) \(X_N\)

  • The first line contains an integer \(N\) representing the number of telescopes, an integer \(S\) representing the number of the starting telescope, and an integer \(Q\) representing the number of moves, separated by spaces.
  • The second line contains integers \(X_1, X_2, \ldots, X_N\) representing the coordinates of each telescope, separated by spaces.
  • \(X_i\) represents the coordinate of telescope \(i\).

【输出】

Print on one line the number of the telescope where the participant is after \(Q\) moves.

【输入样例】

3 1 3
1 3 6

【输出样例】

2

【解题思路】

image

【代码详解】

#include <bits/stdc++.h>
using namespace std;
const int N = 200005;
#define int long long
int n, q, s;  // n: 人数,q: 步数,s: 起始人的编号
int vis[N], vis_time[N], res_pos, res_id;  // vis: 访问序列,vis_time: 访问时间,res_pos: 结果位置,res_id: 结果编号
struct Node
{
    int x, id, pos;  // x: 坐标,id: 原始编号,pos: 排序后的位置
} a[N];
int cord[N], nxt_pos[N], pos_new[N], orig[N];  // nxt_pos: 下一个位置,pos_new: 原始编号到排序位置的映射

// 按坐标x排序的比较函数
bool cmp(Node x, Node y)
{
    return x.x < y.x;
}

signed main()
{
    cin >> n >> s >> q;  // 读入人数、起始编号、步数
    
    // 读入每个人的坐标
    for (int i = 1; i <= n; i++)
    {
        cin >> a[i].x;
        a[i].id = i;  // 记录原始编号
    }
    
    // 按坐标排序
    sort(a + 1, a + n + 1, cmp);
    
    // 建立映射关系
    for (int i = 1; i <= n; i++)
    {
        a[i].pos = i;  // 排序后的位置
        pos_new[a[i].id] = i;  // 原始编号 -> 排序位置
    }
    
    // 预处理每个位置的下一个位置
    for (int i = 1; i <= n; i++)
    {
        if (i == 1)  // 最左边的人
        {
            nxt_pos[i] = i + 1;  // 只能向右
        }
        else if (i == n)  // 最右边的人
        {
            nxt_pos[i] = i - 1;  // 只能向左
        }
        else
        {
            int left = a[i].x - a[i - 1].x;  // 到左边人的距离
            int right = a[i + 1].x - a[i].x;  // 到右边人的距离
            if (left < right)  // 左边更近
            {
                nxt_pos[i] = i - 1;
            }
            else if (left > right)  // 右边更近
            {
                nxt_pos[i] = i + 1;
            }
            else  // 距离相等
            {
                if (a[i - 1].id < a[i + 1].id)  // 左边人编号更小
                {
                    nxt_pos[i] = i - 1;
                }
                else  // 右边人编号更小
                {
                    nxt_pos[i] = i + 1;
                }
            }
        }
    }

    // 模拟移动过程,寻找循环
    int cur = pos_new[s];  // 当前位置(排序后的位置)
    int time = 0, cnt = 0;  // time: 当前时间,cnt: 访问过的位置数量
    memset(vis_time, -1, sizeof(vis_time));  // 初始化访问时间为-1
    
    while (vis_time[cur] == -1)  // 如果当前位置未被访问过
    {
        vis_time[cur] = time;  // 记录访问时间
        vis[cnt++] = cur;  // 记录访问序列
        cur = nxt_pos[cur];  // 移动到下一个位置
        time++;  // 时间增加
    }

    int cycle_start = vis_time[cur];  // 循环开始的时间
    int cycle_length = time - cycle_start;  // 循环长度
    
    // 计算第q步后的位置
    if (q < cnt)  // 如果在循环开始之前
    {
        res_pos = vis[q];
    }
    else  // 如果进入循环
    {
        int pos_in_cycle = (q - cycle_start) % cycle_length;  // 在循环中的位置
        res_pos = vis[cycle_start + pos_in_cycle];
    }
    
    cout << a[res_pos].id << endl;  // 输出结果编号
    return 0;
}

【运行结果】

3 1 3
1 3 6
2

E - Organizing the Bookshelf

【题目来源】

AtCoder:E - Organizing the Bookshelf

【题目描述】

There are \(N\) books arranged in a horizontal row on Takahashi's bookshelf. Initially, the book at the \(i\)-th position from the left has a durability of \(D_i\).
高桥的书架上水平排列着 \(N\) 本书。初始时,从左数第 \(i\) 个位置上的书的耐久度为 \(D_i\)

Takahashi performs \(Q\) operations on this bookshelf in order. In the \(j\)-th operation, an integer \(T_j\) is given, and the following procedure is carried out:
高桥按顺序对这个书架执行 \(Q\) 次操作。在第 \(j\) 次操作中,给出一个整数 \(T_j\),并执行以下过程:

  1. Let \(M\) be the number of books currently remaining on the bookshelf.
    \(M\) 为当前书架上剩余书籍的数量。
  2. If \(T_j > M\), the \(T_j\)-th book from the left does not exist, so nothing happens.
    如果 \(T_j > M\),则从左数第 \(T_j\) 本书不存在,因此不进行任何操作。
  3. If \(T_j \leq M\), the durability of the book currently at the \(T_j\)-th position from the left on the bookshelf is decreased by \(1\). If the durability becomes \(0\), that book is immediately removed from the bookshelf. All books that were to the right of the removed book shift one position to the left, so that no gaps remain among the remaining books.
    如果 \(T_j \leq M\),则将当前书架上从左数第 \(T_j\) 个位置上的书的耐久度减少 \(1\)。如果耐久度变为 \(0\),该书立即从书架移除。被移除书籍右侧的所有书籍向左移动一个位置,以确保剩余书籍之间没有空隙。

After each operation (including cases where nothing happens), output the number of books remaining on the bookshelf.
每次操作后(包括未发生任何操作的情况),输出书架上剩余的书籍数量。

【输入】

\(N\) \(Q\)
\(D_1\) \(D_2\) \(\ldots\) \(D_N\)
\(T_1\)
\(T_2\)
\(\vdots\)
\(T_Q\)

  • The first line contains two space-separated integers: \(N\), the initial number of books, and \(Q\), the number of operations.
  • The second line contains \(N\) space-separated integers \(D_1, D_2, \ldots, D_N\), where \(D_i\) represents the durability of the \(i\)-th book from the left.
  • Each of the following \(Q\) lines contains a single integer \(T_j\) \((1 \leq j \leq Q)\), representing the target position for the \(j\)-th operation.

【输出】

Output \(Q\) lines. The \(j\)-th line should contain the number of books remaining on the bookshelf after the \(j\)-th operation.

【输入样例】

5 5
1 2 3 1 2
2
4
2
1
3

【输出样例】

5
4
3
2
2

【解题思路】

image

【代码详解】

#include <bits/stdc++.h>
using namespace std;
const int N = 200005;
int n, q, tn;  // n: 初始书籍数量,q: 操作次数,tn: 当前剩余书籍数量
int d[N], tr[N];  // d[i]: 第i个位置书的耐久度,tr: 树状数组

// 计算x的二进制表示中最低位的1所代表的值
int lowbit(int x)
{
    return x & -x;
}

// 树状数组的更新操作:在位置x增加c
void add(int x, int c)
{
    for (int i = x; i <= n; i += lowbit(i))
    {
        tr[i] += c;
    }
}

// 树状数组的查询操作:查询前缀和[1, x]
int query(int x)
{
    int res = 0;
    for (int i = x; i; i -= lowbit(i))
    {
        res += tr[i];
    }
    return res;
}

// 通过二分查找找到第x本书的实际位置
int find(int x)
{
    int l = 1, r = n;
    while (l < r)
    {
        int mid = (l + r) / 2;
        if (query(mid) >= x)  // 如果前mid个位置中至少有x本书
        {
            r = mid;  // 向左搜索
        }
        else
        {
            l = mid + 1;  // 向右搜索
        }
    }
    return l;  // 返回第x本书的实际位置
}

int main()
{
    cin >> n >> q;  // 读入初始书籍数量和操作次数
    
    // 初始化
    for (int i = 1; i <= n; i++)
    {
        cin >> d[i];  // 读入每本书的耐久度
        add(i, 1);  // 树状数组中每个位置初始有1本书
    }
    tn = n;  // 当前剩余书籍数量初始为n
    
    while (q--)  // 处理每个操作
    {
        int t;
        cin >> t;  // 读入操作目标位置
        
        if (t > tn)  // 如果目标位置大于当前剩余书籍数量
        {
            cout << tn << endl;  // 输出剩余书籍数量
            continue;  // 继续下一个操作
        }
        
        // 找到第t本书在当前书架上的实际位置
        int pos = find(t);
        
        // 减少该书的耐久度
        d[pos]--;
        
        // 如果耐久度降为0,移除该书
        if (d[pos] == 0)
        {
            add(pos, -1);  // 树状数组中该位置减少1本书
            tn--;  // 剩余书籍数量减1
        }
        
        cout << tn << endl;  // 输出操作后的剩余书籍数量
    }
    
    return 0;
}

【运行结果】

5 5
1 2 3 1 2
2
5
4
4
2
3
1
2
3
2
posted @ 2026-03-17 11:27  团爸讲算法  阅读(2)  评论(0)    收藏  举报