AtCoder Beginner Contest 428
A - Grandma's Footsteps
题意:总共\(x\)秒,每\(a\)秒每秒跑\(s\)米,然后停止\(b\)秒。如此循环求总共跑多少秒。
模拟即可。
点击查看代码
#include <bits/stdc++.h>
using i64 = long long;
void solve() {
int s, a, b, x;
std::cin >> s >> a >> b >> x;
int ans = 0;
int t = 0;
while (t <= x) {
int c = std::min(x - t, a);
ans += c * s;
t += c;
t += b;
}
std::cout << ans << "\n";
}
int main() {
std::ios::sync_with_stdio(false), std::cin.tie(0), std::cout.tie(0);
int t = 1;
// std::cin >> t;
while (t -- ) {
solve();
}
return 0;
}
B - Most Frequent Substrings
题意:一个字符串,求每个长度为\(k\)的子串出现了多少次,然后求最大次数以及出现次数最大的使用子串。
每个子串求一个出现次数就行。
点击查看代码
#include <bits/stdc++.h>
using i64 = long long;
void solve() {
int n, k;
std::cin >> n >> k;
std::string s;
std::cin >> s;
std::map<std::string, int> mp;
for (int i = 0; i + k - 1 < n; ++ i) {
std::string t = s.substr(i, k);
int cnt = 0;
for (int j = 0; j + k - 1 < n; ++ j) {
if (t == s.substr(j, k)) {
++ cnt;
}
}
mp[t] = std::max(mp[t], cnt);
}
std::vector<std::string> ans;
int max = 0;
for (auto & [t, cnt] : mp) {
if (cnt > max) {
ans.clear();
ans.push_back(t);
max = cnt;
} else if (cnt == max) {
ans.push_back(t);
}
}
std::cout << max << "\n";
for (auto & t : ans) {
std::cout << t << " \n"[t == ans.back()];
}
}
int main() {
std::ios::sync_with_stdio(false), std::cin.tie(0), std::cout.tie(0);
int t = 1;
// std::cin >> t;
while (t -- ) {
solve();
}
return 0;
}
C - Brackets Stack Query
题意:每次加左括号或者右括号,或者删除最后一个括号。求每次操作后是不是合法括号序列。
括号序列要合法,记左括号为\(1\)右括号为\(-1\),那么每个位置前缀和都大于等于\(0\)且最后和为\(0\)。那么记录一下前缀和,把小于\(0\)的位置记一下。每次要每次小于\(0\)的位置且最后和为\(0\)才合法。
点击查看代码
#include <bits/stdc++.h>
using i64 = long long;
void solve() {
int Q;
std::cin >> Q;
std::vector<int> a(Q + 1);
int p = 0;
std::set<int> s;
while (Q -- ) {
int op;
std::cin >> op;
if (op == 1) {
char c;
std::cin >> c;
if (c == '(') {
a[p + 1] = a[p] + 1;
++ p;
} else {
a[p + 1] = a[p] - 1;
++ p;
}
if (a[p] < 0) {
s.insert(p);
}
} else {
if (a[p] < 0) {
s.erase(p);
}
-- p;
}
if (s.empty() && a[p] == 0) {
std::cout << "Yes\n";
} else {
std::cout << "No\n";
}
}
}
int main() {
std::ios::sync_with_stdio(false), std::cin.tie(0), std::cout.tie(0);
int t = 1;
// std::cin >> t;
while (t -- ) {
solve();
}
return 0;
}
D - 183184
题意:给你\(C, D\),求有多少\(f(C, C + x)\)是平方数,其中\(x \in [1, D]\),\(f(a, b)\)为\(a\)后面拼接\(b\)构成的数字。
记\(f(C, X)\) = \(C \times 10^t+ X\),其中\(t\)是\(X\)的位数,\(X \in [C + 1, C + D]\)。那,那么对于一个\(t\),\(X \in [\max(C + 1, 10^{t-1}, \min(C + D, 10^t - 1]\),则\(k^2 \in [C \times 10^t + \max(C + 1, 10^{t-1}, C \times 10^t + \min(C + D, 10^t - 1]\),\(k \in [\lceil \sqrt{C \times 10^t + \max(C + 1, 10^{t-1}} \rceil, \lfloor \sqrt{C \times 10^t + \min(C + D, 10^t - 1} \rfloor]\)。枚举\(t\)即可。
点击查看代码
#include <bits/stdc++.h>
using i64 = long long;
i64 floor(i64 x) {
i64 r = sqrtl((long double)x);
while ((r + 1) > 0 && (r + 1) * (r + 1) <= x) {
++ r;
}
while (r > 0 && r * r > x) {
-- r;
}
return r;
}
i64 ceil(i64 x) {
i64 r = floor(x);
if (r * r < x) {
++ r;
}
return r;
}
int get(i64 n) {
int d = 0;
while (n) {
n /= 10;
++ d;
}
return std::max(d, 1);
}
void solve() {
i64 p10[20]{};
p10[0] = 1;
for (int i = 1; i < 20; ++ i) {
p10[i] = p10[i - 1] * 10;
}
i64 C, D;
std::cin >> C >> D;
i64 ans = 0;
i64 L = C + 1;
i64 R = C + D;
int x = get(L);
int y = get(R);
for (int t = x; t <= y; ++ t) {
i64 lo = std::max(L, p10[t - 1]);
i64 hi = std::min(R, p10[t] - 1);
if (lo > hi) {
continue;
}
i64 base = C * p10[t];
i64 klo = ceil(base + lo);
i64 khi = floor(base + hi);
if (klo <= khi) {
ans += (khi - klo + 1);
}
}
std::cout << ans << "\n";
}
int main() {
std::ios::sync_with_stdio(false), std::cin.tie(0), std::cout.tie(0);
int t = 1;
std::cin >> t;
while (t -- ) {
solve();
}
return 0;
}
E - Farthest Vertex
题意:一棵树,求距离每个最远的点是哪个,有多个选编号最大的。
经典结论,树上距离一个点最优的点一定是一条直径的端点。
那么可以求距离\(1\)最远最大的端点,然后求离这个点最远最大点,就知道了距离一个点的直径两端最大的点。然后比较一下距离。
点击查看代码
#include <bits/stdc++.h>
using i64 = long long;
void solve() {
int n;
std::cin >> n;
std::vector<std::vector<int>> adj(n);
for (int i = 1; i < n; ++ i) {
int u, v;
std::cin >> u >> v;
-- u, -- v;
adj[u].push_back(v);
adj[v].push_back(u);
}
auto bfs = [&](int s, std::vector<int> & d) -> int {
std::queue<int> q;
std::fill(d.begin(), d.end(), -1);
q.push(s);
d[s] = 0;
while (q.size()) {
int u = q.front(); q.pop();
for (auto & v : adj[u]) {
if (d[v] == -1) {
d[v] = d[u] + 1;
q.push(v);
}
}
}
int res = 0;
for (int i = 1; i < n; ++ i) {
if (d[i] >= d[res]) {
res = i;
}
}
return res;
};
std::vector<int> d1(n), d2(n);
int p = bfs(0, d1);
int q = bfs(p, d1);
bfs(q, d2);
for (int i = 0; i < n; ++ i) {
if (d1[i] > d2[i]) {
std::cout << p + 1 << "\n";
} else if (d1[i] < d2[i]) {
std::cout << q + 1 << "\n";
} else {
std::cout << std::max(p, q) + 1 << "\n";
}
}
}
int main() {
std::ios::sync_with_stdio(false), std::cin.tie(0), std::cout.tie(0);
int t = 1;
// std::cin >> t;
while (t -- ) {
solve();
}
return 0;
}