当前位置: 首页 > news >正文

AtCoder Beginner Contest 413

比赛链接如下:Denso Create Programming Contest 2025(AtCoder Beginner Contest 413) - AtCoder 

A - Content Too Large

Problem Statement
Takahashi has N items and one bag.

The size of the i-th (1≤i≤N) item is Ai​, and the size of the bag is M.

If and only if the total size of the items he is trying to put in the bag is at most M, he can put all those items in the bag simultaneously.

If he can put all N items in the bag simultaneously, print Yes; otherwise, print No.

解题思路:

一次性将N件物品装入大小为M的包中, 能装进去, 输出Yes, 否则, 输出No

#include <bits/stdc++.h>
using namespace std;
void solve() {int n,m;cin>>n>>m;vector<int> a(n);int sum_a=0;for(int i=0;i<n;i++){cin>>a[i];sum_a+=a[i];}if(sum_a<=m){cout<<"Yes"<<'\n';}else{cout<<"No"<<'\n';}
}
int main() {int t=1;// cin >> t;while (t--) {solve();}return 0;
}

 B - cat 2

Problem Statement
You are given N types of strings S1​,S2​,…,SN​.

You perform the following operation once:

Choose distinct integers i and j (1≤i≤N,1≤j≤N) and concatenate Si​ and Sj​ in this order.
How many different strings can be obtained as a result of this operation?

If different choices of (i,j) result in the same concatenated string, it is counted as one string.

解题思路:

将两个下标不同的字符串进行合并, 然后存入到一个set中, 输出set的长度即可 

#include <bits/stdc++.h>
using namespace std;
void solve() {int n;cin >> n;vector<string> a(n);for (int i = 0; i < n; i++) {cin >> a[i];}set<string> st;for (int i = 0; i < n; i++) {for (int j = 0; j < n; j++) {if (i == j)continue;st.insert(a[i] + a[j]);}}cout << st.size() << '\n';
}
int main() {int t = 1;// cin >> t;while (t--) {solve();}return 0;
}

 C - Large Queue

Problem Statement
There is an empty integer sequence A=(). You are given Q queries, and you need to process them in the given order. There are two types of queries:

Type 1: Given in the format 1 c x. Add c copies of x to the end of A.
Type 2: Given in the format 2 k. Remove the first k elements from A and output the sum of the removed k integers. It is guaranteed that k is at most the length of A at that time.

    解题思路:

    两种操作, 一种是在A的尾部添加c个x, 另一种是移除A的前k个元素, k的值不能超过A的长度, 同时输出这个k个元素的总和,使用deque维护这个数组A, 然后t=1/2进行操作即可

    #include <bits/stdc++.h>
    using namespace std;
    using ll = long long;
    using pll = pair<ll, ll>;
    void solve() {int q;cin >> q;deque<pll> dp;while (q--) {int t;cin >> t;if (t == 1) {ll c, x;cin >> c >> x;dp.emplace_back(c, x);} else {ll k;cin >> k;ll sum = 0;while (k > 0 && !dp.empty()) {auto& a = dp.front();ll c = a.first;  ll x = a.second;  if (c <= k) {sum += c * x;k -= c;dp.pop_front();} else {sum += k * x;a.first -= k;k = 0;}}cout << sum << "\n";}}
    }
    int main() {int t=1;// cin>>t;while(t--){solve();}return 0;
    }
    

     D - Make Geometric Sequence

    Problem Statement
    You are given an integer sequence A=(A1​,A2​,…,AN​) of length N. It is guaranteed that for any i (1≤i≤N), Ai​ is not 0.

    Determine whether there exists a permutation B=(B1​,B2​,…,BN​) of A such that B forms a geometric sequence.

    A sequence S=(S1​,S2​,…,SN​) is a geometric sequence if there exists a real number r such that Si+1​=rSi​ for all integers 1≤i<N.

    Solve T test cases per input file.

    解题思路:

    判断数组A的某个排列能否构成等比数列

    1. 数组长度<=2的数列是等比数列

    2. 数组元素相等, 公比q=1

    3. 公比q正负交替的情况(互为相反数)

    => 只有两个值,且互为相反数,数量差不大于1

    4. 一般情况通过 b[i]^2 = b[i-1]*b[i+1]进行判断

    #include <bits/stdc++.h>
    using namespace std;
    using ll = long long;
    using pll = pair<ll, ll>;
    void solve() {int n;cin >> n;vector<ll> a(n);for (int i = 0; i < n; i++) {cin >> a[i];}if (n <= 2) {cout << "Yes" << '\n';return;}bool f = true;for (int i = 1; i < n; i++) {if (a[i] != a[0]) {f = false;break;}}if (f) {cout << "Yes" << '\n';return;}set<ll> v(a.begin(), a.end());if (v.size() == 2) {auto it = v.begin();ll v1 = *it;it++;ll v2 = *it;if (v1 + v2 == 0) {ll c1 = 0, c2 = 0;for (ll x : a) {if (x == v1)c1++;elsec2++;}if (abs(c1 - c2) <= 1) {cout << "Yes" << '\n';return;}}}sort(a.begin(), a.end(), [](ll x, ll y) { return llabs(x) < llabs(y); });bool f_1 = true;for (int i = 1; i + 1 < n; i++) {ll x = (ll)a[i] * a[i];ll y = (ll)a[i - 1] * a[i + 1];if (x != y) {f_1 = false;break;}}if (f_1)cout << "Yes" << '\n';elsecout << "No" << '\n';
    }
    int main() {int t;cin >> t;while (t--) {solve();}return 0;
    }
    

     E - Reverse 2^i

    Problem Statement
    You are given a permutation P=(P0​,P1​,…,P2N−1​) of (1,2,3,…,2N).

    You can perform the following operation any number of times (possibly zero):

    Choose non-negative integers a,b satisfying 0≤a×2b<(a+1)×2b≤2N, and reverse Pa×2b​,Pa×2b+1​,…,P(a+1)×2b−1​. Here, reversing Pa×2b​,Pa×2b+1​,…,P(a+1)×2b−1​ means simultaneously replacing Pa×2b​,Pa×2b+1​,…,P(a+1)×2b−1​ with P(a+1)×2b−1​,P(a+1)×2b−2​,…,Pa×2b​.
    Find the lexicographically smallest permutation P that can be obtained by repeating the operation.

    You are given T test cases, so find the answer for each.

    解题思路:

    你有一个长度为 2^n 的排列 P,你可以对它做若干次以下操作:

    选择两个整数 a,b,满足区间 [a⋅2^b,(a+1)⋅2^b−1] 在数组范围内,把这个区间反转。

    你要找到经过若干次这种操作后,能得到的字典序最小的排列。

    观察可得:

    每次反转的区间长度必须是 2^b,并且是从 a⋅2^b 开始(即按块划分)。

    实际上这与 对二叉划分结构的左右子树进行翻转是等价的。

    在二叉树的每一级都尝试“原顺序”或“左右块交换”,递归比较返回最小结果

    #include <bits/stdc++.h>
    using namespace std;
    using ll = long long;
    using pll = pair<ll, ll>;
    vector<ll> dfs(vector<ll>& a, int i, int j) {if (j == 0) {return {a[i]};}auto x = dfs(a, i, j - 1);auto y = dfs(a, i + (1 << (j - 1)), j - 1);vector<ll> m;m.insert(m.end(), x.begin(), x.end());m.insert(m.end(), y.begin(), y.end());vector<ll> t;t.insert(t.end(), y.begin(), y.end());t.insert(t.end(), x.begin(), x.end());if (m <= t) {return m;} else {return t;}
    }
    void solve() {int n;cin >> n;vector<ll> a(1 << n);for (int i = 0; i < (1 << n); i++) {cin >> a[i];}vector<ll> ans = dfs(a, 0, n);for (int i = 0; i < (1 << n); i++) {cout << ans[i];if (i < ans.size() - 1)cout << ' ';elsecout << '\n';}
    }
    int main() {int t;cin >> t;while (t--) {solve();}return 0;
    }
    

     F - No Passag  


    Probl

    em Statement
    There is an H×W grid. Let (i,j) denote the cell at the i-th row from the top and j-th column from the left. Among these, K cells are goals. The i-th goal (1≤i≤K) is cell (Ri​,Ci​).

    Takahashi and Aoki play a game using this grid and a single piece placed on the grid. Takahashi and Aoki repeatedly perform the following series of operations until the piece reaches a goal cell:

    Aoki chooses an integer a between 1 and 4, inclusive.
    Then, Takahashi chooses an integer b between 1 and 4, inclusive, where a=b must be satisfied. Let (i,j) be the cell where the piece is placed before the operation. Based on the chosen integer b and the piece's position, move the piece.
    When b=1: If (i−1,j) is within the grid, move the piece from cell (i,j) to cell (i−1,j); if it is outside the grid, do nothing.
    When b=2: If (i+1,j) is within the grid, move the piece from cell (i,j) to cell (i+1,j); if it is outside the grid, do nothing.
    When b=3: If (i,j−1) is within the grid, move the piece from cell (i,j) to cell (i,j−1); if it is outside the grid, do nothing.
    When b=4: If (i,j+1) is within the grid, move the piece from cell (i,j) to cell (i,j+1); if it is outside the grid, do nothing.
    Takahashi's objective is to minimize the number of moves until the piece reaches a goal. Aoki's objective is to prevent the piece from reaching the goal; if that is impossible, his objective is to maximize the number of moves until the piece reaches a goal.

    For all pairs of integers (i,j) satisfying 1≤i≤H,1≤j≤W, solve the following problem and find the sum of all solutions:

    Start the game with the piece at cell (i,j). Assume both players act optimally toward their respective objectives. If Takahashi can make the piece reach a goal, the solution is the minimum number of moves; otherwise, the solution is 0.

    解题思路:

    1.dp[i] 表示从 i 出发走到目标所需最小步数

    2.用 Dijkstra 从目标反向扩展

    3. Aoki 选 1~4 中一项,Takahashi 从剩下中选最优方向。确保最坏情况最优

    4. 对于每个点,找出在任意 Aoki 决策下,Takahashi 的最小可行步数,再加一更新

    5. 最后,  累加所有的dp[i]

    #include <bits/stdc++.h>
    using namespace std;
    const int INF = 0x3f3f3f3f;
    using pii = pair<int, int>;
    const int dr[5] = {0, -1, 1, 0, 0};
    const int dc[5] = {0, 0, 0, -1, 1};
    void solve() {int H, W, K;cin >> H >> W >> K;vector<int> dp(H * W, INF);vector<char> g(H * W, 0);for (int i = 0; i < K; i++) {int r, c;cin >> r >> c;--r, --c;int id = r * W + c;g[id] = 1;dp[id] = 0;}auto fun = [&](int r, int c) { return r >= 0 && r < H && c >= 0 && c < W; };priority_queue<pii, vector<pii>, greater<>> pq;for (int i = 0; i < H * W; i++) {if (g[i])pq.emplace(0, i);}while (!pq.empty()) {auto [cost, id] = pq.top();pq.pop();if (cost > dp[id])continue;int r = id / W, c = id % W;for (int dir = 1; dir <= 4; dir++) {int nr = r + dr[dir], nc = c + dc[dir];if (!fun(nr, nc))continue;int ni = nr * W + nc;int d[4];for (int i = 0; i < 4; i++) {int ar = nr + dr[i + 1], ac = nc + dc[i + 1];if (fun(ar, ac))d[i] = dp[ar * W + ac];elsed[i] = INF;}int m1 = INF, m2 = INF;for (int i = 0; i < 4; i++) {if (d[i] < m1) {m2 = m1;m1 = d[i];} else if (d[i] < m2) {m2 = d[i];}}int w = 0;for (int i = 0; i < 4; i++) {int k = (d[i] > m1 ? m1 : m2);w = max(w, k);}int c = w >= INF ? INF : w + 1;if (c < dp[ni]) {dp[ni] = c;pq.emplace(c, ni);}}}long long ans = 0;for (int x : dp) {if (x < INF)ans += x;}cout << ans << '\n';
    }
    int main() {solve();return 0;
    }
    

    G - Big Banned Grid

    Problem Statement
    There is an H×W grid. Let (i,j) denote the cell at the i-th row (1≤i≤H) from the top and j-th column (1≤j≤W) from the left.

    Each cell in the grid either has an obstacle placed on it or has nothing placed on it. There are K cells with obstacles: cells (r1​,c1​),(r2​,c2​),…,(rK​,cK​).

    Takahashi is initially at cell (1,1) and wants to reach cell (H,W) by repeatedly moving to an adjacent cell (up, down, left, right) that has nothing placed on it.

    More precisely, he can repeat the following operation as many times as he likes:

    Choose one of the following four operations and perform the chosen operation:
    If 1<i and cell (i−1,j) has nothing placed on it, move to cell (i−1,j). Otherwise, do not move.
    If 1<j and cell (i,j−1) has nothing placed on it, move to cell (i,j−1). Otherwise, do not move.
    If i<H and cell (i+1,j) has nothing placed on it, move to cell (i+1,j). Otherwise, do not move.
    If j<W and cell (i,j+1) has nothing placed on it, move to cell (i,j+1). Otherwise, do not move.
    Determine whether he can move from cell (1,1) to cell (H,W).

    解题思路:

    如果有一条线能将(1,1)和(H,W)在网格中分割成两个独立的块, 两点就无法形成通路

    实现上, 我们可以, 

    为四个边界创建虚拟节点(编号k到k+3):

    k:上边界(x=1)

    k+1:下边界(x=n)

    k+2:左边界(y=1)

    k+3:右边界(y=m)

    如果障碍物在边界上,将其与对应虚拟节点合并

    遍历每个障碍物,检查它的8个方向(上下左右+对角线)

    如果邻域存在其他障碍物,合并它们的集合

    最后, 如果存在下面四种情况就说明两点被隔断了

    上边界和下边界连通(k和k+1)

    上边界和左边界连通(k和k+2)

    左边界和右边界连通(k+2和k+3)

    下边界和右边界连通(k+1和k+3)

    #include <bits/stdc++.h>
    using namespace std;
    class UnionFind {vector<int> fa, sz;
    public:int cc;UnionFind(int n) : fa(n), sz(n, 1), cc(n) { iota(fa.begin(), fa.end(), 0); }int find(int x) { return fa[x] == x ? x : fa[x] = find(fa[x]); }bool merge(int x, int y) {x = find(x), y = find(y);if (x == y)return false;if (sz[x] > sz[y])swap(x, y);fa[x] = y;sz[y] += sz[x];cc--;return true;}
    };
    void solve() {int n, m, k;cin >> n >> m >> k;map<pair<int, int>, int> mp;vector<pair<int, int>> p(k);UnionFind uf(k + 5);for (int i = 0; i < k; i++) {cin >> p[i].first >> p[i].second;mp[p[i]] = i;if (p[i].first == 1)uf.merge(i, k);if (p[i].first == n)uf.merge(i, k + 1);if (p[i].second == 1)uf.merge(i, k + 2);if (p[i].second == m)uf.merge(i, k + 3);}for (int i = 0; i < k; i++) {int x = p[i].first, y = p[i].second;for (int dx = -1; dx <= 1; dx++) {for (int dy = -1; dy <= 1; dy++) {if (dx == 0 && dy == 0)continue;auto it = mp.find({x + dx, y + dy});if (it != mp.end()) {uf.merge(i, it->second);}}}}bool ans = uf.find(k) == uf.find(k + 1) || uf.find(k) == uf.find(k + 2) ||uf.find(k + 2) == uf.find(k + 3) ||uf.find(k + 1) == uf.find(k + 3);cout << (ans ? "No" : "Yes") << '\n';
    }
    int main() {solve();return 0;
    }

     感谢大家的点赞和关注,你们的支持是我创作的动力!

     

    http://www.dtcms.com/a/273268.html

    相关文章:

  • 并发编程原理与实战(十六)深入锁的演进,为什么有了synchronized还需要Lock?
  • UECC-UE连接协调的运作方式
  • (一)OpenCV——噪声去除(降噪)
  • React--Fiber 架构
  • 数据库操作核心知识点整理
  • mac m1芯片 安装pd及win10系统
  • 第12讲—一元函数积分学的物理应用
  • 在vscode中安装jupyter
  • 电机电角度与机械角度的个人理解:从蒙圈到理解到放弃
  • 蓝桥云课 矩形切割-Java
  • 快速分页wpf
  • npx cowsay 让动物说话~
  • Java重试+事务的方式优化saveBatch,配置信息修改
  • Flink Exactly Once 和 幂等
  • 【郑大二年级信安小学期】Day9:XSS跨站攻击XSS绕过CSRF漏洞SSRF漏洞
  • 服务器深夜告警?可能是攻击前兆!
  • Unity插件——ABC详解
  • AI驱动的低代码革命:解构与重塑开发范式
  • LeetCode 8. 字符串转换整数 (atoi)
  • 【保姆级喂饭教程】idea中安装Conventional Commit插件
  • FreeRTOS—任务创建和删除的API函数和方法
  • 书生实训营第二关:大模型对战
  • 列表初始化
  • C++ Lambda 表达式详解
  • 《棒垒球知道》奥运会的吉祥物是什么·棒球1号位
  • 【c++八股文】Day6:using和typedef
  • [yolo-world]YOLO-World数据集介绍及标注格式详解
  • SoC程序如何使用单例模式运行
  • 什么是 MIT License?核心要点解析
  • [数据结构与算法] 优先队列 | 最小堆 C++