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();
}
}
C - Snuke the Cookie Picker
题目大意
给定一个图,由.
和#
组成,其中的#
理应组成一个矩形区域,但是现在缺了一块,需要我们找出缺的这一块。
解题思路
我们通过扫描整个图中的#
,通过坐标最值可以找到矩形的边界,那么扫描矩形区域,出现.
就是缺的地方了。
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();
}
}
E - Art Gallery on Graph
题目大意
给定一个无权无向图,其上有 \(k\) 个卫士,每个卫士有保卫范围 \(h_i\),距离卫士距离不超过 \(h_i\) 的点都可以被保卫,现在求被保卫的点。
解题思路
实际上就是让我们去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
题目大意
给定一个 \(n\) 点 \(m\) 边无权连通无向图,起始时位于 \(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();
}
}
- 题解 Beginner AtCoder Contest 305beginner atcoder contest 305 题解beginner atcoder contest contest programming beginner atcoder beginner atcoder contest 296 beginner atcoder contest 295 beginner atcoder contest abcde beginner atcoder contest 335 beginner atcoder contest 332 beginner atcoder contest 328 beginner atcoder contest 334