AtCoder Beginner Contest 305 题解 A - F

A - Water Station

题目大意

找到离给定的数最近的一个 5 的倍数输出即可。

解题思路

我们取这个数对 5 的上下界,也就是整数除以 5 再乘以 5,以及这个数再加上一个 5,比较这两数和给定数的距离即可。

AC Code

#include <iostream> #include <algorithm> #include <cstring> #define endl '\n' #define ios ios::sync_with_stdio(false), cin.tie(nullptr), cout.tie(nullptr) using namespace std; typedef long long LL; const int N = 1e5 + 10; const int MOD = 1e9 + 7; void solve() { int x; cin >> x; int a = x / 5 * 5, b = a + 5; if (b - x < x - a) { cout << b << endl; } else { cout << a << endl; } } signed main() { ios; int T = 1; // cin >> T; while (T--) { solve(); } }

B - ABCDEFG

题目大意

题图给定数轴,表示这七个字符的相对位置关系,求任意两者的距离。

解题思路

人脑预处理出前缀和,直接相减即可。

AC Code

#include <iostream> #include <algorithm> #include <cstring> #define endl '\n' #define ios ios::sync_with_stdio(false), cin.tie(nullptr), cout.tie(nullptr) using namespace std; typedef long long LL; const int N = 1e5 + 10; const int MOD = 1e9 + 7; int s[] = {0, 3, 4, 8, 9, 14, 23}; void solve() { char a, b; cin >> a >> b; if (a > b) swap(a, b); cout << s[b - 'A'] - s[a - 'A'] << endl; } signed main() { ios; int T = 1; // cin >> T; while (T--) { solve(); } }

题目大意

给定一个图,由.#组成,其中的#理应组成一个矩形区域,但是现在缺了一块,需要我们找出缺的这一块。

解题思路

我们通过扫描整个图中的#,通过坐标最值可以找到矩形的边界,那么扫描矩形区域,出现.就是缺的地方了。

AC Code

#include <iostream> #include <algorithm> #include <cstring> #define endl '\n' #define ios ios::sync_with_stdio(false), cin.tie(nullptr), cout.tie(nullptr) using namespace std; typedef long long LL; const int N = 1010; const int MOD = 1e9 + 7; string g[N]; void solve() { int h, w; cin >> h >> w; for (int i = 1; i <= h; ++i) { cin >> g[i]; g[i] = '0' + g[i]; } int x1 = 0, x2 = h, y1 = 0, y2 = w; for (int i = 1; i <= h; ++i) { for (int j = 1; j <= w; ++j) { if (g[i][j] == '#') { y1 = max(y1, j); y2 = min(y2, j); x1 = max(x1, i); x2 = min(x2, i); } } } for (int i = x2; i <= x1; ++i) { for (int j = y2; j <= y1; ++j) { if (g[i][j] == '.') { cout << i << ' ' << j << endl; } } } } signed main() { ios; int T = 1; // cin >> T; while (T--) { solve(); } }

D - Sleep Log

题目大意

给出高橋さん的睡眠时间表,奇数项是起床时间,偶数是睡觉时间,有 q 次询问,每次给出一个区间,问这段时间高橋さん睡了多长时间。

解题思路

一维区间询问,可以使用前缀和,考虑到给定的区间会把原来的睡眠时间分割开,使用二分找到第一个不小于区间端点的元素位置,修正分割量即可。

AC Code

#include <iostream> #include <algorithm> #include <cstring> #define endl '\n' #define ios ios::sync_with_stdio(false), cin.tie(nullptr), cout.tie(nullptr) using namespace std; typedef long long LL; const int N = 4e5 + 10; const int MOD = 1e9 + 7; int a[N], s[N]; void solve() { int n; cin >> n; for (int i = 1; i <= n; ++i) { cin >> a[i]; s[i] = s[i - 1] + (a[i] - a[i - 1]) * (i & 1); } int q; cin >> q; for (int i = 1; i <= q; ++i) { int l, r; cin >> l >> r; int idl = lower_bound(a + 1, a + n + 1, l) - a; int idr = lower_bound(a + 1, a + n + 1, r) - a; LL cnt = 0; if (idr & 1) { cnt += a[idr] - r; } if (idl & 1) { cnt += l - a[idl - 1]; } cout << s[idr] - s[idl - 1] - cnt << endl; } } signed main() { ios; int T = 1; // cin >> T; while (T--) { solve(); } }

题目大意

给定一个无权无向图,其上有 k 个卫士,每个卫士有保卫范围 hi,距离卫士距离不超过 hi 的点都可以被保卫,现在求被保卫的点。

解题思路

实际上就是让我们去dijkstra以卫士为中心的最短路,并且标记所有经过的点,最后汇总输出即可。

AC Code

#include <iostream> #include <algorithm> #include <cstring> #include <queue> #define endl '\n' #define ios ios::sync_with_stdio(false), cin.tie(nullptr), cout.tie(nullptr) using namespace std; typedef long long LL; const int N = 4e5 + 10; const int MOD = 1e9 + 7; struct Guard{ int p; int h; bool operator< (const Guard& t) const{ return h < t.h; } }; bool vis[N]; int res[N]; int n, m, k, idx; int H[N], e[N], ne[N]; void add(int a, int b) { e[idx] = b; ne[idx] = H[a]; H[a] = idx++; } void dijkstra() { priority_queue<Guard> heap; for (int i = 1; i <= k; ++i) { int p, h; cin >> p >> h; heap.push({p, h}); } for (int i = 1; i <= n; ++i) { while (!heap.empty()) { auto top = heap.top(); heap.pop(); if (vis[top.p]) continue; vis[top.p] = true; if (top.h) { for (int j = H[top.p]; ~j; j = ne[j]) { if (!vis[e[j]]) { heap.push({e[j], top.h - 1}); } } } } } } void solve() { cin >> n >> m >> k; memset(H, -1, sizeof H); for (int i = 1; i <= m; ++i) { int a, b; cin >> a >> b; add(a, b); add(b, a); } dijkstra(); LL cnt = 0; for (int i = 1; i <= n; ++i) { if (vis[i]) { res[++cnt] = i; } } cout << cnt << endl; for (int i = 1; i <= cnt; ++i) { cout << res[i] << ' '; } } signed main() { ios; int T = 1; // cin >> T; while (T--) { solve(); } }

F - Dungeon Explore

题目大意

给定一个 nm 边无权连通无向图,起始时位于 1 点,允许我们移动最多 2n 次到达 n 点。每次走向一个新的结点,都会得知该点附近链接点的信息。

解题思路

我们需要从 1 走到 n,同时,每次只能直到自己当前所在位置的临接点,这个过程很类似于dfs的过程,如果我们dfs,实际上是将每个点都遍历一遍,那么除去头尾两点,其他点至多入一次出一次,所以最后的移动次数会略小于 2n 可解。

另:交互题一定要关ios,忘记关了TLE了5次qwq。

AC Code

#include <iostream> #include <algorithm> #include <cstring> //#define endl '\n' //#define ios ios::sync_with_stdio(false), cin.tie(nullptr), cout.tie(nullptr) using namespace std; typedef long long LL; const int N = 110; const int MOD = 1e9 + 7; bool vis[N]; int n, m; void dfs(int u) { vis[u] = true; if (u == n) exit(0); int num; cin >> num; int ne[N]; for (int i = 1; i <= num; ++i) { cin >> ne[i]; } for (int i = 1; i <= num; ++i) { if (!vis[ne[i]]) { cout << ne[i] << endl; dfs(ne[i]); cout << u << endl; for (int j = 0; j <= num; ++j) { int xxcwasdfad; cin >> xxcwasdfad; } } } } void solve() { cin >> n >> m; dfs(1); } signed main() { // ios; int T = 1; // cin >> T; while (T--) { solve(); } }

__EOF__

本文作者叁纔
本文链接https://www.cnblogs.com/SanCai-Newbie/p/17481658.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。您的鼓励是博主的最大动力!
posted @   叁纔  阅读(25)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
· 【杂谈】分布式事务——高大上的无用知识?
点击右上角即可分享
微信分享提示