A. Equally
模拟
代码实现
a, b, c = sorted(map(int, input().split())) ans = a == b == c or a+b == c print('Yes' if ans else 'No')
B. Santa Claus 1
模拟
代码实现
#include <bits/stdc++.h> #define rep(i, n) for (int i = 0; i < (n); ++i) using namespace std; int main() { int h, w, si, sj; cin >> h >> w >> si >> sj; --si; --sj; vector<string> s(h); rep(i, h) cin >> s[i]; string t; cin >> t; int ans = 0; for (char c : t) { int ni = si, nj = sj; if (c == 'U') ni--; if (c == 'D') ni++; if (c == 'L') nj--; if (c == 'R') nj++; if (s[ni][nj] == '#') continue; si = ni; sj = nj; if (s[si][sj] == '@') { s[si][sj] = '.'; ++ans; } } cout << si+1 << ' ' << sj+1 << ' ' << ans << '\n'; return 0; }
C. Illuminate Buildings
枚举间隔 ,起点为 ,在这样的子序列中找最长相同连续段即可
时间复杂度为
代码实现
#include <bits/stdc++.h> #define rep(i, n) for (int i = 0; i < (n); ++i) using namespace std; int main() { int n; cin >> n; vector<int> h(n); rep(i, n) cin >> h[i]; int ans = 0; for (int w = 1; w <= n; ++w) { rep(si, w) { vector<int> a; for (int i = si; i < n; i += w) { a.push_back(h[i]); } int val = -1, len = 0; for (int x : a) { if (val == x) len++; else val = x, len = 1; ans = max(ans, len); } } } cout << ans << '\n'; return 0; }
D. Santa Claus 2
对于每个房子的位置,可以对它的每种横坐标维护它对应的所有纵坐标,对每种纵坐标维护它对应的所有横坐标(这个是老套路了
每次移动需要完成以下的需求:
- 获取当前方向上的第一个房子的位置
- 从对应的两个横纵集合里删掉这个位置
可以用 map<int, set<int>>
来维护
代码实现
#include <bits/stdc++.h> #define rep(i, n) for (int i = 0; i < (n); ++i) using namespace std; using ll = long long; using D = map<ll, set<ll>>; int main() { int n, m; ll sx, sy; cin >> n >> m >> sx >> sy; D xs, ys; rep(i, n) { int x, y; cin >> x >> y; xs[y].insert(x); ys[x].insert(y); } int ans = 0; auto f = [&](D& xs, D& ys, ll y, ll l, ll r) { if (l > r) swap(l, r); auto& st = xs[y]; while (1) { auto it = st.lower_bound(l); if (it == st.end()) break; if (*it > r) break; ys[*it].erase(y); st.erase(it); ans++; } }; rep(mi, m) { char d; int c; cin >> d >> c; ll nx = sx, ny = sy; if (d == 'U') ny += c; if (d == 'D') ny -= c; if (d == 'R') nx += c; if (d == 'L') nx -= c; if (sy == ny) f(xs, ys, sy, sx, nx); else f(ys, xs, sx, sy, ny); sx = nx, sy = ny; } cout << sx << ' ' << sy << ' ' << ans << '\n'; return 0; }
E. Snowflake Tree
不难看出最终的树只有三层
先枚举中心点,然后对中心点周围的点的度数做降序排序,再枚举中心点的每个邻接点,因为已经做降序排序了,那么从当前点开始往左的所有兄弟节点的度数就一定大于等于当前点,假设已经枚举到了第 个点,那么就能分成 组,每组的点数都是 (构成一颗子树),再加上中心点就是最终留下来的点数,那么用 减去保留下来的点数就是需要删掉的点数了
时间复杂度为
代码实现
#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; cin >> n; vector<vector<int>> to(n); rep(i, n-1) { int a, b; cin >> a >> b; --a; --b; to[a].push_back(b); to[b].push_back(a); } vector<int> deg(n); rep(i, n) deg[i] = to[i].size(); int ans = n; rep(v, n) { vector<int> d; for (int u : to[v]) d.push_back(deg[u]); ranges::sort(d, greater<>()); rep(i, deg[v]) { int now = d[i]*(i+1) + 1; ans = min(ans, n-now); } } cout << ans << '\n'; return 0; }
F. Visible Buildings
先对所有点 跑凸包
然后取凸包上每条边的直线在 轴上的截距的最大值就是答案
如果所有截距 ,则无解
代码实现
#include <bits/stdc++.h> #define rep(i, n) for (int i = 0; i < (n); ++i) using namespace std; using ll = long long; struct V { ll x, y; V(ll x=0, ll y=0): x(x), y(y) {} V& operator+=(const V& v) { x += v.x; y += v.y; return *this; } V& operator+(const V& v) const { return V(*this) += v; } V& operator-=(const V& v) { x -= v.x; y -= v.y; return *this; } V& operator-(const V& v) const { return V(*this) -= v; } V& operator*=(ll s) { x *= s; y *= s; return *this; } V& operator*(ll s) const { return V(*this) *= s; } V& operator/=(ll s) { x /= s; y /= s; return *this; } V& operator/(ll s) const { return V(*this) /= s; } ll dot(const V& v) const { return x*v.x + y*v.y; } ll cross(const V& v) const { return x*v.y - v.x*y; } }; istream& operator>>(istream& is, V& v) { is >> v.x >> v.y; return is; } ostream& operator<<(ostream& os, const V& v) { os << "(" << v.x << "," << v.y << ")"; return os; } int main() { int n; cin >> n; double ans = -100; bool all = true; vector<V> conv; rep(i, n) { ll x, h; cin >> x >> h; V p(x, h); while (conv.size() >= 2) { V a = conv.back(), b = conv.end()[-2]; if ((p.y-a.y)*(p.x-b.x) < (p.y-b.y)*(p.x-a.x)) break; conv.pop_back(); } if (conv.size() >= 1) { V a = conv.back(); ll dy = a.y-p.y, dx = p.x-a.x; double y = double(dy*p.x + p.y*dx)/dx; if ((a.y-p.y)*p.x >= -p.y*(p.x-a.x)) all = false; ans = max(ans, y); } conv.push_back(p); } if (all) puts("-1"); else printf("%.10f\n", ans); return 0; }
G. Counting Buildings
考虑对每个建筑按高度从到到小进行放置
假设已经放置了一些建筑,现在考虑插入一个新的新的建筑,如果插在最左边,那么 ,如果插在最右边,那么 ,插在其他位置没有影响
记 dp[i][j]
表示已经插了 个数且当前的 的方案数
对于
有 种插法的贡献为 ,有 种插法的贡献为 ,有 种插法的贡献为
写成生成函数就是 ,等价于
然后跑分治 即可
代码实现
#include <bits/stdc++.h> #include <atcoder/all> using namespace atcoder; #define rep(i, n) for (int i = 0; i < (n); ++i) using namespace std; using mint = modint998244353; using fps = vector<mint>; int main() { int n, k; cin >> n >> k; queue<fps> q; q.push(fps(1, 1)); rep(i, n-1) { fps f(3, 1); f[1] = i; q.push(f); } while (q.size() >= 2) { auto a = q.front(); q.pop(); auto b = q.front(); q.pop(); q.push(convolution(a, b)); } auto f = q.front(); mint ans = f[k+(n-1)]; cout << ans.val() << '\n'; return 0; }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库
· SQL Server 2025 AI相关能力初探
· 为什么 退出登录 或 修改密码 无法使 token 失效