牛客周赛 Round 57

1|0A - 小红喜欢1


#include<bits/stdc++.h> using namespace std; using i32 = int32_t; using i64 = long long; using i128 = __int128; using vi = vector<int>; using pii = pair<int, int>; const int inf = INT_MAX / 2; i32 main() { ios::sync_with_stdio(false), cin.tie(nullptr); for(int i = 1 , x ; i <= 5 ; i ++) { cin >> x; if(x == 1) cout << i; } return 0; }

2|0B - 小红的树切割


要切割的边,端点一定同色。

#include<bits/stdc++.h> using namespace std; using i32 = int32_t; using i64 = long long; using i128 = __int128; using vi = vector<int>; using pii = pair<int, int>; const int inf = INT_MAX / 2; i32 main() { ios::sync_with_stdio(false), cin.tie(nullptr); int n; cin >> n; string s; cin >> s; int cnt = 0; for (int i = 1, x, y; i < n; i++) { cin >> x >> y, x--, y--; if(s[x] == s[y]) cnt ++; } cout << cnt; return 0; }

3|0C - 小红的双好数(easy)


二进制下,一定只有 01n进制下,一定是10

#include<bits/stdc++.h> using namespace std; using i32 = int32_t; using i64 = long long; using i128 = __int128; using vi = vector<int>; using pii = pair<int, int>; const int inf = INT_MAX / 2; bool check(int x, int y) { while (x) { if (x % y > 1) return false; x /= y; } return true; } i32 main() { ios::sync_with_stdio(false), cin.tie(nullptr); i64 n; cin >> n; if (n == 1) cout << "YES\n2 3\n"; else if (n == 2) cout << "NO\n"; else cout << "YES\n2 " << n << "\n"; return 0; }

4|0D - 小红的线段


点可以分成三种,y>kx+b,y=kx+b,y<kx+b。然后需要有交点的,最优解是选择一个大于的和一个小于的,其次是选择一个大于(小于)和等于,最后是两个等于,剩余的情况怎么连接都没有交点,所以随便连就好了。

#include<bits/stdc++.h> using namespace std; using i32 = int32_t; using i64 = long long; using i128 = __int128; #define int i64 using vi = vector<int>; using pii = pair<int, int>; const int inf = INT_MAX / 2; i32 main() { ios::sync_with_stdio(false), cin.tie(nullptr); int n, k, b; cin >> n >> k >> b; vi A, B, C; for (int i = 1, N = n * 2, x, y, yy; i <= N; i++) { cin >> x >> y; yy = k * x + b; if (y == yy) C.push_back(i); else if (y > yy) A.push_back(i); else B.push_back(i); } vector<pii> res; while (not A.empty() and not B.empty()) { res.emplace_back(A.back(), B.back()); A.pop_back(), B.pop_back(); } while (not A.empty() and not C.empty()) { res.emplace_back(A.back(), C.back()); A.pop_back(), C.pop_back(); } while (not C.empty() and not B.empty()) { res.emplace_back(C.back(), B.back()); C.pop_back(), B.pop_back(); } assert(C.size() % 2 == 0); for (int i = 1; i < C.size(); i += 2) res.emplace_back(C[i - 1], C[i]); cout << res.size() << "\n"; for (auto &[x, y]: res) cout << x << " " << y << " Y\n"; for (int i = 1; i < A.size(); i += 2) cout << A[i - 1] << " " << A[i] << " N\n"; for (int i = 1; i < B.size(); i += 2) cout << B[i - 1] << " " << B[i] << " N\n"; return 0; }

5|0E - 小红的双好数(hard)


枚举k2进制下只有0,1的数,然后验证k1进制下即可。复杂度O(218×logk210)

#include<bits/stdc++.h> using namespace std; using i32 = int32_t; using i64 = long long; using i128 = __int128; #define int i64 using vi = vector<int>; using pii = pair<int, int>; const int inf = INT_MAX / 2; i32 main() { ios::sync_with_stdio(false), cin.tie(nullptr); int k1, k2; cin >> k1 >> k2; int N = 1e18; vi p(1, 1); while (p.back() * k2 <= N) p.push_back(p.back() * k2); auto check = [k1](int x) { if (x < 2) return false; while (x) { if (x % k1 > 1) return false; x /= k1; } return true; }; auto dfs = [p, check, N](auto &&self, int x, int i) -> void { if (x > N) return; if (check(x)) { cout << "YES\n" << x << "\n"; exit(0); } if (i == p.size()) return; self(self, x, i + 1); self(self, x + p[i], i + 1); return; }; dfs(dfs, 0, 0); cout << "NO\n"; return 0; }

6|0F - 小红的数组操作


每个数组的最小值可以用std::multiset<int>维护。

前缀最小值可以用线段树维护。

#include<bits/stdc++.h> using namespace std; using i32 = int32_t; using i64 = long long; using i128 = __int128; #define int i64 using vi = vector<int>; using pii = pair<int, int>; const int inf = INT_MAX / 2; struct Node { int l, r, value; Node *left, *right; Node(int l, int r, int value, Node *left, Node *right) : l(l), r(r), value(value), left(left), right(right) {}; }; // 建树 Node *build(int l, int r, const vi &arr) { if (l == r) return new Node(l, r, arr[l], nullptr, nullptr); int mid = (l + r) >> 1; Node *left = build(l, mid, arr), *right = build(mid + 1, r, arr); return new Node(l, r, min(left->value, right->value), left, right); } // 修改 void modify(int l, int r, int v, Node *cur) { if (l > cur->r || r < cur->l) return; if (l <= cur->l && r >= cur->r) { cur->value = v; return; } int mid = (cur->l + cur->r) >> 1; if (l <= mid) modify(l, r, v, cur->left); if (r > mid) modify(l, r, v, cur->right); cur->value = min(cur->left->value, cur->right->value); return; } // 查询 int query(int l, int r, Node *cur) { if (l <= cur->l && r >= cur->r) return cur->value; int mid = (cur->l + cur->r) >> 1, res = inf; if (l <= mid) res = min(res, query(l, r, cur->left)); if (r > mid) res = min(res, query(l, r, cur->right)); return res; } void modify(int x, int v, Node *cur) { modify(x, x, v, cur); } int query(int x, Node *cur) { return query(1, x, cur); } i32 main() { ios::sync_with_stdio(false), cin.tie(nullptr); int n; cin >> n; vector<vi> a(n + 1); vector<multiset<int>> calc(n + 1); vi arr(n + 1); for (int i = 1, m; i <= n; i++) { cin >> m; a[i] = vi(m + 1); for (int j = 1; j <= m; j++) cin >> a[i][j], calc[i].insert(a[i][j]); arr[i] = *calc[i].begin(); } Node *root = build(1, n, arr); int q; cin >> q; for (int opt, i, j, x; q; q--) { cin >> opt; if (opt == 1) { cin >> i >> j >> x; calc[i].erase(calc[i].find(a[i][j])); a[i][j] = x, calc[i].insert(x); if (*calc[i].begin() != arr[i]) arr[i] = *calc[i].begin(), modify(i, arr[i], root); } else { cin >> i; cout << query(i, root) << "\n"; } } return 0; }

7|0G - 小红的双排列构造


在大多数情况下是存在无解的情况,大致的构造思路是

1,2,3,n,1,2,3,,k2,n,n1,n2,,k1

下面说一下几种特例。

  • n=1时,只有1,1一种情况
    • k=2时,1,1是唯一解
    • 其他情况均无解
  • n=2
    • k=1时,1,1,2,2
    • k=2时,1,2,2,1
    • k=3时,1,2,1,2
    • 其他情况无解
  • 其他情况下,不会出现无解的情况,但依旧有特例
    • k=0时,1,1,2,2,3,3,n,n
    • k=1时,1,1,2,3,,n,2,3,4,,n
    • k=2时,1,2,3,,n,n,n1,n2,n3,,1
#include<bits/stdc++.h> using namespace std; using i32 = int32_t; using i64 = long long; using i128 = __int128; #define int i64 using vi = vector<int>; using pii = pair<int, int>; const int inf = INT_MAX / 2; i32 main() { ios::sync_with_stdio(false), cin.tie(nullptr); int n, k; cin >> n >> k; if (n == 1) { if (k == 2) cout << "1 1"; else cout << "-1"; } else if (n == 2) { if (k == 1)cout << "1 1 2 2"; else if (k == 3) cout << "1 2 1 2"; else if (k == 2) cout << "1 2 2 1"; else cout << "-1"; } else if (k == 0) { for (int i = 1; i <= n; i++) cout << i << " " << i << " "; } else if (k == 1) { cout << 1 << " "; for (int i = 1; i <= n; i++) cout << i << " "; for (int i = 2; i <= n; i++) cout << i << " "; } else if (k == 2) { for (int i = 1; i <= n; i++) cout << i << " "; for (int i = n; i >= 1; i--) cout << i << " "; } else { for (int i = 1; i <= n; i++) cout << i << " "; for (int i = 1; i <= k - 2; i++) cout << i << " "; for (int i = n; i > k - 2; i--) cout << i << " "; } return 0; }

__EOF__

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