AtCoder Beginner Contest 303

1|0A - Similar String


#include <bits/stdc++.h> using namespace std; #define int long long int32_t main() { int n; string s , t; cin >> n >> s >> t; for( int i = 0 ; i < n ; i ++ ){ if( s[i] == t[i] ) continue; if( s[i] == '1' && t[i] == 'l' ) continue; if( s[i] == 'l' && t[i] == '1' ) continue; if( s[i] == '0' && t[i] == 'o' ) continue; if( s[i] == 'o' && t[i] == '0' ) continue; cout << "No\n"; return 0; } cout << "Yes\n"; return 0; }

2|0B - Discord


#include <bits/stdc++.h> using namespace std; #define int long long int32_t main() { int n , m; cin >> n >> m; vector<vector<int>> a( n+1 , vector<int>(n+1 , 0 )); for( ; m ; m -- ){ for( int u = -1 , v , i = 1 ; i <= n ; i ++ ){ cin >> v; if( u == -1 ) u = v; else a[u][v] = a[v][u] = 1 , u = v; } } int res = 0; for( int i = 1 ; i <= n ; i ++ ) for( int j = i + 1 ; j <=n ;j ++ ){ if( a[i][j] == 1 ) continue; res ++; } cout << res; return 0; }

3|0C - Dash


模拟就好了,注意每个点的补给只能用一次

#include <bits/stdc++.h> using namespace std; #define int long long int32_t main() { int n , m , h , k; cin >> n >> m >> h >> k; string s; cin >> s; set<pair<int,int>> rec; for( int x , y ; m ; m -- ) cin >> x >> y , rec.emplace( x , y ); int r = 0 , c = 0; for( auto i : s ){ if( h == 0 ){ cout << "No\n"; return 0; } if( i == 'R' ) r ++; else if( i == 'L' ) r --; else if( i == 'U' ) c ++; else c --; h --; if( h < k && rec.count(make_pair(r,c)) ) h = k , rec.erase(make_pair(r,c)); } cout << "Yes\n"; return 0; }

4|0D - Shift vs. CapsLock


f[i][0]表示前i位,且当前CapsLock没按下时的最小花费,f[i][1]表示前i位,且当前CapsLock按下时的最小花费。

然后模拟转移的过程即可。

#include <bits/stdc++.h> using namespace std; #define int long long int32_t main() { int x, y, z, n; string s; cin >> x >> y >> z >> s; n = s.size(); vector<array<int, 2>> f(n + 1, array{(int) 1e18, (int) 1e18}); f[0][0] = 0; for (int i = 1; i <= n; i++) { if (s[i - 1] == 'a') { f[i][0] = min({f[i-1][0] + x, f[i - 1][1] + y + z, f[i - 1][1] + z + x}); f[i][1] = min({f[i-1][1] + y, f[i - 1][0] + x + z, f[i - 1][0] + z + y}); } else { f[i][0] = min({f[i - 1][0] + y, f[i - 1][1] + x + z, f[i - 1][1] + z + y}); f[i][1] = min({f[i - 1][1] + x, f[i - 1][0] + y + z, f[i - 1][0] + z + x}); } } cout << min( f[n][0] , f[n][1] ); return 0; }

5|0E - A Gift From the Stars


我们把星星的中间的点叫做 root 点,我们的任务就是找到所有的 root 点,并且要输出 root 点的度数。

首先我们把最终的树拿出来,所有的叶子点走一步就一定是 root 点 ,而 root 点链接的所有的点都是星星的叶子点,如果星星的叶子点的度数不为 1,就说明了这个星星的叶子点和其他的星星的叶子点相连。

这样的话我们通过一个类似求拓扑序的方式就可以找到所有的 root 点了。

#include <bits/stdc++.h> using namespace std; #define int long long int32_t main() { ios::sync_with_stdio(false), cin.tie(nullptr), cout.tie(nullptr); int n; cin >> n; vector<vector<int>> e(n + 1); vector<int> d(n + 1); for (int i = n - 1, u, v; i; i--) cin >> u >> v, e[u].push_back(v), e[v].push_back(u), d[u]++, d[v]++; queue<int> q; vector<bool> vis(n + 1, 0); vector<int> res; for( int i = 1 ; i <= n ; i ++ ) if( d[i] == 1 ) q.push(i); while( !q.empty() ){ int u = q.front(); q.pop(); if( vis[u] ) continue; vis[u] = 1; int root; for( auto i : e[u] ){ if( vis[i] ) continue; root = i; break; } res.push_back( e[root].size() ); vis[root] = 1; for( auto i : e[root] ){ d[i] --; vis[i] = 1; if( d[i] == 1 ) { for( auto j : e[i] ){ if(vis[j]) continue; q.push(j); break; } } } } sort( res.begin() , res.end() ); for( auto i : res ) cout << i << " "; return 0; }

9C4558897E5E72F34B4C36D04E8D2CBA

然后我们发现所有的图其实都是这种样子的。所以从选择任何一个叶子点作为跟求一遍深度,所有深度为2,5,8,11,14,17的点都一定是 root 点。

#include <bits/stdc++.h> using namespace std; #define int long long vector<vector<int>> e; vector<int> dep; void dfs(int x) { for (auto i: e[x]) { if (dep[i]) continue; dep[i] = dep[x] + 1, dfs(i); } return; } int32_t main() { ios::sync_with_stdio(false), cin.tie(nullptr), cout.tie(nullptr); int n; cin >> n; e = vector<vector<int>>(n + 1); dep = vector<int>(n + 1, 0); for (int i = n - 1, u, v; i; i--) cin >> u >> v, e[u].push_back(v), e[v].push_back(u); for (int i = 1; i <= n; i++) { if (e[i].size() != 1) continue; dep[i] = 1, dfs(i); } vector<int> res; for( int i = 1 ; i <= n ; i ++ ){ if( (dep[i] - 2) % 3 ) continue; res.push_back( e[i].size() ); } sort(res.begin(), res.end()); for (auto i: res) cout << i << " "; return 0; }

6|0F - Damage over Time


首先这道题的难点在于攻击的持续时间无法确定。所以我们考虑二分的方式来枚举攻击的时间。

我们将技能按照ti升序排列。如果剩余时间tti那么技能i造成的伤害就是ti×di,反之伤害就是t×di

这样的话我们维护前缀ti×di的最大值和后缀di的最大值。这样的话我们就可以选择两种中伤害较大的部分。

如果我们选择tti的情况,那么我们就持续使用cnt=tti+1次技能。这样造成的伤害最大cnt×ti×di,之后就只能使用第二种技能。

如果我们使用第二种技能,我们持续使用$cnt= t-\left \lfloor \frac{max1}{d_i} \right \rfloor max1d_i\frac{cnt(t+t+1-cnt)}{x}$

#include<bits/stdc++.h> using namespace std; #define int __int128 #define ll long long #define mp make_pair int read() { int x = 0, f = 1, ch = getchar(); while ((ch < '0' || ch > '9') && ch != '-') ch = getchar(); if (ch == '-') f = -1, ch = getchar(); while (ch >= '0' && ch <= '9') x = (x << 3) + (x << 1) + ch - '0', ch = getchar(); return x * f; } int32_t main() { int n = read(), h = read(); vector<pair<int, int>> a(n); for (auto &[t, d]: a) t = read(), d = read(); sort(a.begin(), a.end()); vector<pair<int, int> > pre(n); pre[0] = mp(a[0].first * a[0].second, a[0].first); for (int i = 1, t; i < a.size(); i++) { pre[i] = pre[i - 1], t = a[i].first * a[i].second; if (t > pre[i].first) pre[i] = mp(t, a[i].first); } vector<int> suf(n + 1, 0); for (int i = n - 1; i >= 0; i--) suf[i] = max(suf[i + 1], a[i].second); int l = 0, r = h, mid, res; auto check = [n, h, a, pre, suf](int x) { int pos = n - 1, cur = h; while (cur > 0 && x > 0) { while (pos >= 0 && a[pos].first > x) pos--; if (pos < 0 || pre[pos].first < suf[pos + 1] * x) { int down = 0; if (pos >= 0) down = pre[pos].first / suf[pos + 1]; int cnt = x - down; int sum = cnt * (x - cnt + 1 + x) / 2 * suf[pos + 1]; cur -= sum, x -= cnt; } else { int cnt = x - pre[pos].second + 1; cur -= cnt * pre[pos].first, x -= cnt; } } return cur <= 0; }; while (l <= r) { mid = (l + r) >> 1; if (check(mid)) res = mid, r = mid - 1; else l = mid + 1; } cout << (ll) res; return 0; }

__EOF__

本文作者PHarr
本文链接https://www.cnblogs.com/PHarr/p/17448335.html
关于博主:前OIer,SMUer
版权声明CC BY-NC 4.0
声援博主:如果这篇文章对您有帮助,不妨给我点个赞
posted @   PHarr  阅读(104)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现
点击右上角即可分享
微信分享提示