AtCoder Beginner Contest 327

1|0A - ab


#include<bits/stdc++.h> using namespace std; #define mp make_pair #define int long long using vi = vector<int>; using pii = pair<int, int>; const int inf = 1e9; int32_t main() { ios::sync_with_stdio(false), cin.tie(nullptr); int n; string s; cin >> n >> s; for( int i = 1 ; i < n ; i ++ ){ if( s[i] == 'a' and s[i-1] == 'b' ) { cout << "Yes\n"; return 0; }else if( s[i] == 'b' and s[i-1] == 'a' ){ cout << "Yes\n"; return 0; } } cout << "No\n"; return 0; }

2|0B - A^A


b = int(input()) a = 1 while (a ** a) < b: a += 1 if (a ** a) == b: print(a) else: print(-1)

3|0C - Number Place


#include<bits/stdc++.h> using namespace std; #define mp make_pair #define int long long using vi = vector<int>; using pii = pair<int, int>; const int inf = 1e9; int power(int x, int y) { int ans = 1; while (y) { if (y & 1) ans = ans * x; x = x * x, y /= 2; } return ans; } int32_t main() { ios::sync_with_stdio(false), cin.tie(nullptr); int n = 9; vector a(n, vi(n)); for (int i = 0; i < n; i++) for (int j = 0; j < n; j++) cin >> a[i][j]; for (int i = 0; i < n; i++) { set<int> vis; for (int j = 0; j < n; j++) vis.insert(a[i][j]); if (vis.size() != n) { cout << "No\n"; return 0; } } for (int i = 0; i < n; i++) { set<int> vis; for (int j = 0; j < n; j++) vis.insert(a[j][i]); if (vis.size() != n) { cout << "No\n"; return 0; } } for (int i = 0; i < n; i += 3) { for (int j = 0; j < n; j += 3) { set<int> vis; for (int x = 0; x < 3; x++) for (int y = 0; y < 3; y++) vis.insert(a[i + x][j + y]); if (vis.size() != n) { cout << "No\n"; return 0; } } } cout << "Yes\n"; return 0; }

4|0D - Good Tuple Problem


赛时的思考还是有些欠缺,一看到这道题,就直接抄了个 2-SAT 的板子,结果还 wa 了一发。

#include<bits/stdc++.h> using namespace std; #define mp make_pair #define int long long using vi = vector<int>; using pii = pair<int, int>; const int inf = 1e9; int N; vector<vi> e; vi dfn, inStk, low, scc; int cnt, sc; stack<int> stk; void tarjan(int x) { low[x] = dfn[x] = ++cnt; inStk[x] = 1, stk.push(x); for (auto y: e[x]) { if (!dfn[y]) { tarjan(y), low[x] = min(low[x], low[y]); } else if (inStk[y]) { low[x] = min(low[x], dfn[y]); } } if (low[x] == dfn[x]) { sc++; for (int y; true;) { y = stk.top(), stk.pop(); inStk[y] = 0, scc[y] = sc; if (x == y) break; } } return; } int32_t main() { ios::sync_with_stdio(false), cin.tie(nullptr); int n, m; cin >> n >> m; vector<int> a(m + 1), b(m + 1); for (int i = 1; i <= m; i++) cin >> a[i]; for (int i = 1; i <= m; i++) cin >> b[i]; N = n * 2 + 2; e = vector<vi>(N); dfn = inStk = low = scc = vi(N); for (int i = 1; i <= m; i++) { if (a[i] == b[i]) { cout << "No\n"; return 0; } e[2 * a[i]].push_back(2 * b[i] + 1); e[2 * a[i] + 1].push_back(2 * b[i]); } for (int i = 2; i <= n * 2 + 1; i++) if (!dfn[i]) tarjan(i); for (int i = 1; i <= n; i++) { if (scc[i * 2] == scc[i * 2 + 1]) { cout << "No\n"; return 0; } } cout << "Yes\n"; return 0; }

其实认真思考后,发现符合条件的情况一定是二分图的,所以直接进行黑白染色就好了。

#include<bits/stdc++.h> using namespace std; #define mp make_pair #define int long long using vi = vector<int>; using pii = pair<int, int>; using ldb = long double; const int inf = 1e9; int32_t main() { ios::sync_with_stdio(false), cin.tie(nullptr); int n, m; cin >> n >> m; vector<vi> e(n); vector<int> a(m), b(m); for (auto &i: a) cin >> i, i--; for (auto &i: b) cin >> i, i--; for (int i = 0; i < m; i++) e[a[i]].push_back(b[i]), e[b[i]].push_back(a[i]); vi v(n + n, -1); auto dfs = [&v, e](auto &&self, int x, int w) -> void { for (auto y: e[x]) { if (v[y] == -1) { v[y] = w ^ 1, self(self, y, v[y]); } else if (v[y] == w) { cout << "No\n"; exit(0); } } }; for (int i = 0; i < n; i++) { if (v[i] >= 0) continue; v[i] = 0; dfs(dfs, i, 0); } cout << "Yes\n"; return 0; }

当然也可以用判定二分图的方式。

5|0E - Maximize Rating


观察式子,发现当k确定时,只有(0.9)kiQi是变换的,其他部分都是常量。对于这个值,可以直接背包求一下。

#include<bits/stdc++.h> using namespace std; #define mp make_pair #define int long long using vi = vector<int>; using pii = pair<int, int>; using ldb = long double; const int inf = 1e9; int32_t main() { ios::sync_with_stdio(false), cin.tie(nullptr); int n; cin >> n; vector<ldb> a(n + 1), q(n + 1), s(n + 1), t(n + 1); for (int i = n; i >= 1; i--) cin >> a[i]; q[1] = 1; for (int i = 2; i <= n; i++) q[i] = q[i - 1] * 0.9; for (int i = 1; i <= n; i++) s[i] = s[i - 1] + q[i]; for (int i = 1; i <= n; i++) t[i] = 1200.0 / sqrt((ldb) i); vector<vector<ldb>> f(n + 1, vector<ldb>(n + 1, -1E18)); ldb res = -1E18; f[0][0] = 0; for (int i = 1; i <= n; i++) { f[i][0] = 0; for (int j = 1; j <= i; j++) { f[i][j] = max(f[i - 1][j], f[i - 1][j - 1] + q[j] * a[i]); res = max(res, f[i][j] / s[j] - t[j]); } } cout << fixed << setprecision(10) << res << "\n"; return 0; }

6|0F - Apples


其实本质上是个二维数点问题,问用w×d的矩形最多可以框选多少个点。

用一种类似扫描线的方式在t时给x加一,然后在t+d时给x减一,这样可以优化掉一维,对于剩下的一维可以采用类似双指针的方式此时复杂度是O(N2)的依旧不行。

我们考虑每次扫描线后每次都是考虑宽度w范围有多少个点,我们不如反过来思考,考虑每个点对那些区间产生贡献,答案是[x,x+w),所以每次对这个区间加一,询问时只要询问全局最优解就好了。

#include<bits/stdc++.h> using namespace std; using pii = pair<int, int>; struct Node { int l, r, maxVal, lazy; Node *left, *right; Node(int l, int r, Node *left, Node *right) : l(l), r(r), left(left), right(right) { maxVal = lazy = 0; } } *root; Node *build(int l, int r) { if (l == r) return new Node(l, r, nullptr, nullptr); int mid = (l + r) / 2; auto left = build(l, mid), right = build(mid + 1, r); return new Node(l, r, left, right); } void pushDown(Node *rt) { rt->left->maxVal += rt->lazy, rt->left->lazy += rt->lazy; rt->right->maxVal += rt->lazy, rt->right->lazy += rt->lazy; rt->lazy = 0; return; } void modify(Node *rt, int l, int r, int v) { if (l > rt->r or r < rt->l) return; if (l <= rt->l and rt->r <= r) { rt->maxVal += v, rt->lazy += v; return; } pushDown(rt); int mid = (rt->l + rt->r) / 2; if (l <= mid) modify(rt->left, l, r, v); if (r > mid) modify(rt->right, l, r, v); rt->maxVal = max(rt->left->maxVal, rt->right->maxVal); return; } const int N = 4e5; int32_t main() { ios::sync_with_stdio(false), cin.tie(nullptr); int n, d, w; cin >> n >> d >> w; vector<vector<pii> > f(N + 1); for (int t, x, i = 1; i <= n; i++) { cin >> t >> x; f[t].emplace_back(x, 1); if (t + d <= N) f[t + d].emplace_back(x, -1); } root = build(1, N); int res = 0; for (int x = 1; x <= N; x++) { for (const auto &[y, v]: f[x]) modify(root, y, min(N, y + w - 1), v); res = max(res, root->maxVal); } cout << res << "\n"; return 0; }

__EOF__

本文作者PHarr
本文链接https://www.cnblogs.com/PHarr/p/17817706.html
关于博主:前OIer,SMUer
版权声明CC BY-NC 4.0
声援博主:如果这篇文章对您有帮助,不妨给我点个赞
posted @   PHarr  阅读(38)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 单元测试从入门到精通
· 上周热点回顾(3.3-3.9)
· winform 绘制太阳,地球,月球 运作规律
历史上的今天:
2022-11-08 Codeforces Round #827
2022-11-08 AtCoder Beginner Contest 275
点击右上角即可分享
微信分享提示