A. Glutton Takahashi
模拟
代码实现
n = int(input()) sweet = False cnt = 0 for i in range(n): s = input() cnt += 1 if s == 'sweet': if sweet: break sweet = True else: sweet = False if cnt == n: print('Yes') else: print('No')
B. Grid Walk
模拟
代码
#include <bits/stdc++.h> #define rep(i, n) for (int i = 0; i < (n); ++i) using namespace std; const int di[] = {-1, 0, 1, 0}; const int dj[] = {0, 1, 0, -1}; int main() { int h, w; cin >> h >> w; int si, sj; cin >> si >> sj; --si; --sj; vector<string> c(h); rep(i, h) cin >> c[i]; string x; cin >> x; map<char, int> mp; rep(v, 4) mp["URDL"[v]] = v; for (char dir : x) { int v = mp[dir]; int ni = si+di[v], nj = sj+dj[v]; if (ni < 0 or nj < 0 or ni >= h or nj >= w) continue; if (c[ni][nj] == '#') continue; si = ni; sj = nj; } cout << si+1 << ' ' << sj+1 << '\n'; return 0; }
C. Minimum Glutton
考虑对其中一个序列做降序排序,这个序列中第一个达到给定值的位置的前缀和就是待定的最小可能的操作次数
然后对两个序列得到的结果取最小值即可
代码实现
#include <bits/stdc++.h> #define rep(i, n) for (int i = 0; i < (n); ++i) using namespace std; using ll = long long; int f(vector<int> a, ll x) { ranges::sort(a, greater<>()); rep(i, a.size()) { x -= a[i]; if (x < 0) return i+1; } return a.size(); } int main() { int n; ll x, y; cin >> n >> x >> y; vector<int> a(n), b(n); rep(i, n) cin >> a[i]; rep(i, n) cin >> b[i]; int ans = min(f(a, x), f(b, y)); cout << ans << '\n'; return 0; }
D. K-th Nearest
二分答案
假设答案为 ,考虑以b为圆心, 为半径的圆,判断在 这个范围内的点数是否
对于区间内的点数可以用两个二分实现,也就是分别找到两个边界的左边的点数,然后二者作差即可
代码实现
#include <bits/stdc++.h> #define rep(i, n) for (int i = 0; i < (n); ++i) using namespace std; using ll = long long; int main() { int n, q; cin >> n >> q; vector<int> a(n); rep(i, n) cin >> a[i]; ranges::sort(a); rep(qi, q) { int b, k; cin >> b >> k; auto f = [&](int wj) -> bool { int l = b-wj, r = b+wj; int li = ranges::lower_bound(a, l) - a.begin(); int ri = ranges::lower_bound(a, r+1) - a.begin(); return ri-li >= k; }; int wa = -1, ac = 2e8; while (ac-wa > 1) { int wj = (ac+wa)/2; if (f(wj)) ac = wj; else wa = wj; } cout << ac << '\n'; } return 0; }
E. Maximum Glutton
考虑dp出不超过 和 时能吃的菜的最大值,最后答案就是在它基础上+1即可
记 dp[i][j][k]
表示从前 道菜中选择若干道菜满足甜度总和为 且咸度总和为 时的最大个数
状态数就是 ,显然要寄
考虑将个数和咸度总和交换位置
重新定义dp:
记 dp[i][j][k]
表示从前 道才中选 道菜满足甜度总和为 时的咸度总和的最小值
代码实现
#include <bits/stdc++.h> #define rep(i, n) for (int i = 0; i < (n); ++i) using namespace std; inline void chmin(int& a, int b) { if (a > b) a = b; } int main() { int n, x, y; cin >> n >> x >> y; const int INF = 1001001001; vector dp(n+1, vector<int>(x+1, INF)); dp[0][0] = 0; rep(i, n) { int a, b; cin >> a >> b; vector old(n+1, vector<int>(x+1, INF)); swap(dp, old); rep(j, n+1)rep(k, x+1) { int now = old[j][k]; if (now == INF) continue; chmin(dp[j][k], old[j][k]); // not use if (k+a <= x) chmin(dp[j+1][k+a], now+b); // use } } int ans = 0; rep(j, n+1)rep(k, x+1) if (dp[j][k] <= y) { ans = max(ans, j); } if (ans < n) ans++; cout << ans << '\n'; return 0; }
F. Range Connect MST
不妨假设在连续的相邻两个点之间有一条边,在区间 中的每个点和 连一条边,这意味着,区间 中的每条边都变成了无用边,可以删除,容易发现只要把 个点中的 条边删除自然就能得到生成树。
然后用 std::set
来模拟这个过程即可。
代码实现
#include <bits/stdc++.h> #define rep(i, n) for (int i = 0; i < (n); ++i) using namespace std; using ll = long long; int main() { int n, q; cin >> n >> q; set<int> cut; rep(i, n-1) cut.insert(i); vector<tuple<int, int, int>> qs; rep(qi, q) { int l, r, c; cin >> l >> r >> c; --l; --r; qs.emplace_back(c, l, r); } ranges::sort(qs); ll ans = 0; for (auto [c, l, r] : qs) { ans += c; auto it = cut.lower_bound(l); while (it != cut.end() and *it < r) { cut.erase(it++); ans += c; } } if (cut.size() != 0) ans = -1; cout << ans << '\n'; return 0; }
G. Last Major City
最小斯坦纳树的板题
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 使用C#创建一个MCP客户端
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现