KAJIMA CORPORATION CONTEST 2025 (AtCoder Beginner Contest 394)
A - 22222
点击查看代码
void solve() {
std::string s;
std::cin >> s;
int cnt = std::count(s.begin(), s.end(), '2');
std::cout << std::string(cnt, '2') << "\n";
}
B - cat
点击查看代码
void solve() {
int n;
std::cin >> n;
std::vector<std::string> s(n);
for (int i = 0; i < n; ++ i) {
std::cin >> s[i];
}
std::sort(s.begin(), s.end(), [&](std::string & a, std::string & b) {
return a.size() < b.size();
});
for (auto & x : s) {
std::cout << x;
}
std::cout << "\n";
}
C - Debug
题意:给你一个字符串,把
从后往前做。
点击查看代码
void solve() {
std::string s;
std::cin >> s;
int n = s.size();
for (int i = n - 1; i ; -- i) {
if (s[i - 1] == 'W' && s[i] == 'A') {
s[i - 1] = 'A'; s[i] = 'C';
}
}
std::cout << s << "\n";
}
D - Colorful Bracket Sequence
题意:有三种括号,问这个序列是否是合法的括号序列。
用栈存左括号,每次遇到右括号看栈顶的括号能不能和它匹配就行。
点击查看代码
void solve() {
std::string s;
std::cin >> s;
std::map<char, char> mp;
mp['['] = ']';
mp['('] = ')';
mp['<'] = '>';
std::stack<char> stk;
for (auto & c : s) {
if (mp.count(c)) {
stk.push(c);
} else if (stk.empty() || mp[stk.top()] != c) {
std::cout << "No\n";
return;
} else {
stk.pop();
}
}
if (stk.size()) {
std::cout << "No\n";
return;
}
std::cout << "Yes\n";
}
E - Palindromic Shortest Path
题意:给你一个邻接矩阵,权值为一个小写字母,求每个
建立一个正向图和一个反向图,把
点击查看代码
void solve() {
int n;
std::cin >> n;
std::vector<std::string> s(n);
for (int i = 0; i < n; ++ i) {
std::cin >> s[i];
}
std::vector<std::array<std::vector<int>, 26>> adj1(n), adj2(n);
for (int i = 0; i < n; ++ i) {
for (int j = 0; j < n; ++ j) {
if (s[i][j] != '-') {
adj1[i][s[i][j] - 'a'].push_back(j);
adj2[j][s[i][j] - 'a'].push_back(i);
}
}
}
std::vector d(n, std::vector<int>(n, -1));
std::queue<std::pair<int, int>> q;
for (int i = 0; i < n; ++ i) {
d[i][i] = 0;
q.push({i, i});
}
for (int i = 0; i < n; ++ i) {
for (int j = 0; j < n; ++ j) {
if (i == j) {
continue;
}
if (s[i][j] != '-') {
d[i][j] = 1;
q.push({i, j});
}
}
}
while (q.size()) {
auto [u, v] = q.front(); q.pop();
for (int i = 0; i < 26; ++ i) {
for (auto & x : adj2[u][i]) {
for (auto & y : adj1[v][i]) {
if (d[x][y] == -1) {
d[x][y] = d[u][v] + 2;
q.push({x, y});
}
}
}
}
}
for (int i = 0; i < n; ++ i) {
for (int j = 0; j < n; ++ j) {
std::cout << d[i][j] << " \n"[j == n - 1];
}
}
}
F - Alkane
题意:给你一棵树,要求满足每个点度数要么是1要么是4且最少有一个度数是4的节点的子图中节点数最多的。
考虑树形
点击查看代码
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);
}
std::vector<int> f(n);
int ans = 0;
auto dfs = [&](auto self, int u, int fa) -> void {
f[u] = 1;
std::vector<int> a;
for (auto & v : adj[u]) {
if (v == fa) {
continue;
}
self(self, v, u);
a.push_back(f[v]);
}
std::sort(a.begin(), a.end(), std::greater<int>());
if (a.size() >= 3) {
f[u] = std::max(f[u], a[0] + a[1] + a[2] + 1);
if (a.size() >= 4) {
ans = std::max(ans, a[0] + a[1] + a[2] + a[3] + 1);
}
if (u != 0) {
ans = std::max(ans, f[u] + 1);
}
}
};
dfs(dfs, 0, -1);
if (ans == 0) {
ans = -1;
}
std::cout << ans << "\n";
}
G - Dense Buildings
题意:有一个
显然在移动过程中,会先下降到一个最低点,然后上升到目标楼层。那么如果我们知道了这个最低点,就可以一开始直接下到这个点,然后就可以沿着这条路径上的楼一直到目标楼,然后再上到目标楼层,代价是
那么我们可以建图,
点击查看代码
struct DSU {
std::vector<int> fa, cnt;
DSU(int _n) {
init(_n);
}
void init(int _n) {
fa.assign(_n, 0);
cnt.assign(_n, 1);
std::iota(fa.begin(), fa.end(), 0);
}
int find(int x) {
return x == fa[x] ? x : fa[x] = find(fa[x]);
}
bool merge(int x, int y) {
x = find(x), y = find(y);
if (x == y) {
return false;
}
fa[y] = x;
cnt[x] += cnt[y];
return true;
}
bool same(int x, int y) {
return find(x) == find(y);
}
int size(int x) {
return cnt[find(x)];
}
};
void solve() {
int n, m;
std::cin >> n >> m;
std::vector h(n, std::vector<int>(m));
for (int i = 0; i < n; ++ i) {
for (int j = 0; j < m; ++ j) {
std::cin >> h[i][j];
}
}
auto get = [&](int x, int y) -> int {
return x * m + y;
};
std::vector<std::array<int, 3>> edges;
for (int i = 0; i < n; ++ i) {
for (int j = 0; j < m; ++ j) {
if (i + 1 < n) {
edges.push_back({std::min(h[i][j], h[i + 1][j]), get(i, j), get(i + 1, j)});
}
if (j + 1 < m) {
edges.push_back({std::min(h[i][j], h[i][j + 1]), get(i, j), get(i, j + 1)});
}
}
}
std::sort(edges.begin(), edges.end(), std::greater<>());
std::vector<std::vector<std::pair<int, int>>> adj(n * m);
DSU dsu(n * m);
for (auto & [w, u, v] : edges) {
if (dsu.same(u, v)) {
continue;
}
dsu.merge(u, v);
adj[u].push_back({v, w});
adj[v].push_back({u, w});
}
const int lg = std::__lg(n * m) + 1, inf = 2e9;
std::vector f(n * m, std::vector<int>(lg + 1));
std::vector min(n * m, std::vector<int>(lg + 1, inf));
std::vector<int> d(n * m);
std::queue<int> q;
q.push(0);
d[0] = 1;
while (q.size()) {
int u = q.front(); q.pop();
for (auto & [v, w] : adj[u]) {
if (d[v] == 0) {
d[v] = d[u] + 1;
f[v][0] = u;
min[v][0] = w;
for (int j = 1; j <= lg; ++ j) {
f[v][j] = f[f[v][j - 1]][j - 1];
min[v][j] = std::min(min[v][j - 1], min[f[v][j - 1]][j - 1]);
}
q.push(v);
}
}
}
auto lca = [&](int x, int y) -> int {
if (d[x] < d[y]) {
std::swap(x, y);
}
int res = inf;
for (int i = lg; i >= 0; -- i) {
if (d[f[x][i]] >= d[y]) {
res = std::min(res, min[x][i]);
x = f[x][i];
}
}
if (x == y) {
return res;
}
for (int i = lg; i >= 0; -- i) {
if (f[x][i] != f[y][i]) {
res = std::min({res, min[x][i], min[y][i]});
x = f[x][i];
y = f[y][i];
}
}
res = std::min({res, min[x][0], min[y][0]});
return res;
};
int Q;
std::cin >> Q;
while (Q -- ) {
int a, b, x, c, d, y;
std::cin >> a >> b >> x >> c >> d >> y;
-- a, -- b, -- c, -- d;
int u = get(a, b), v = get(c, d);
if (u == v) {
std::cout << std::abs(x - y) << "\n";
continue;
}
int min = std::min({x, y, lca(u, v)});
std::cout << x + y - 2 * min << "\n";
}
}
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 在鹅厂做java开发是什么体验
· 百万级群聊的设计实践
· WPF到Web的无缝过渡:英雄联盟客户端的OpenSilver迁移实战
· 永远不要相信用户的输入:从 SQL 注入攻防看输入验证的重要性
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析