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;
}
posted @ 2025-10-18 22:17  maburb  阅读(123)  评论(0)    收藏  举报