RioTian: 牛客小白月赛30(个人题解)
黑白边
https://ac.nowcoder.com/acm/contest/9667/A
最近沉迷写前端代码,现在缓过来简单补下
比赛链接:https://ac.nowcoder.com/acm/contest/9667#question
建议在博客园中阅读以便获取更好阅读体验感:https://www.cnblogs.com/RioTian/p/14099560.html
A:黑白边
简单的并查集模板
B:最好的宝石
待补
C:滑板上楼梯
math
// Author : RioTian // Time : 20/12/07 #include <bits/stdc++.h> using namespace std; typedef long long ll; const int N = 1e5 + 10; int main() { // freopen("in.txt", "r", stdin); ios::sync_with_stdio(false), cin.tie(0), cout.tie(0); ll n, cnt = 0; cin >> n; ll ans = n / 4; cnt += ans * 2; ans = n % 4; if (ans < 3) cnt += ans; else cnt++; cout << cnt << endl; }
D:GCD
素数筛反向选
// Author : RioTian #include <bits/stdc++.h> using namespace std; typedef long long ll; const int N = 1e5 + 10; int n; bool isPrime[N]; int main() { // freopen("in.txt", "r", stdin); ios::sync_with_stdio(false), cin.tie(0), cout.tie(0); cin >> n; int cnt = 0; for (int i = 2; i <= n; i++) { if (!isPrime[i]) { cnt++; for (int j = i * 2; j <= n; j += i) { isPrime[j] = 1; } } } // cout << cnt << endl; cout << (n <= 3 ? -1 : cnt + 2) << endl; }
E:牛牛的加法
模拟题
如果两数字位数不同就先补零便于后面处理
// Author : RioTian // Time : 20/12/07 #include <bits/stdc++.h> using namespace std; typedef long long ll; const int N = 1e5 + 10; string a, b, ans; int cot = 0, len; bool lin; int main() { // freopen("in.txt", "r", stdin); ios::sync_with_stdio(false), cin.tie(0), cout.tie(0); cin >> a >> b; if (a.size() > b.size()) { cot = a.size() - b.size(); while (cot--) b = '0' + b; } else { cot = b.size() - a.size(); while (cot--) a = '0' + a; } len = a.size(); ans = ""; lin = true; for (int i = 0; i < len; i++) { if ((a[i] - '0' + b[i] - '0') % 10 == 0 && lin) continue; lin = false; ans += (char)((a[i] - '0' + b[i] - '0') % 10 + '0'); } if (ans.size() == 0) ans += "0"; cout << ans << endl; }
F:石子合并
模拟一下样例1,会发现16 + 15,容易发下16为5项和,而
// Author : RioTian // Time : 20/12/07 #include <bits/stdc++.h> using namespace std; typedef long long ll; const int N = 2e5 + 10; int n; ll a[N]; int main() { // freopen("in.txt", "r", stdin); ios::sync_with_stdio(false), cin.tie(0), cout.tie(0); cin >> n; for (int i = 1; i <= n; ++i) cin >> a[i]; ll cnt = 0, Max = 0; for (int i = 1; i <= n; ++i) { Max = max(Max, a[i]); cnt += a[i]; } cout << Max * (n - 2) + cnt; }
G:滑板比赛
类似二分图,在满足条件的情况下尽量增加匹配数。
直接写二分图肯定很麻烦,但转过来一想,为数组排序呢?
$$
// Author : RioTian // Time : 20/12/07 #include <bits/stdc++.h> using namespace std; typedef long long ll; const int N = 2e5 + 10; int n, m; ll a[N], b[N]; int main() { // freopen("in.txt", "r", stdin); ios::sync_with_stdio(false), cin.tie(0), cout.tie(0); cin >> n >> m; for (int i = 1; i <= n; ++i) cin >> a[i]; for (int i = 1; i <= m; ++i) cin >> b[i]; sort(a + 1, a + 1 + n); sort(b + 1, b + 1 + m); int i, j; int ans = 0, l = 1, r = n; for (i = m; i >= 1; i--) { if (b[i] < a[r]) r--, ans++; else l++; } cout << ans << endl; }
H:第 k 小
看到题的瞬间想用线段树,但简单算了下时间复杂度,可能会超时,所以转而想了想主席树(没了解的同学可以看这里:Here),但觉得牛客应该不会在小白赛出这种码量大的题。
被迫无奈看了下题解,发现原来快速写下优先队列即可(都没想到这个)
以下是AC代码
// Author : RioTian // Time : 20/12/07 #include <bits/stdc++.h> using namespace std; typedef long long ll; const int N = 2e5 + 10; ll a[N]; priority_queue<ll> que; int main() { // freopen("in.txt", "r", stdin); ios::sync_with_stdio(false), cin.tie(0), cout.tie(0); int n, m, k; cin >> n >> m >> k; for (int i = 1; i <= n; ++i) cin >> a[i]; sort(a + 1, a + 1 + n); int ans = min(n, k); for (int i = 1; i <= ans; ++i) que.push(a[i]); int opt, x; while (m--) { cin >> opt; if (opt == 1) { cin >> x; if (que.size() <= k - 1) que.push(x); else { if (x > que.top()) continue; que.push(x), que.pop(); } } else { if (que.size() != k) cout << -1 << endl; else cout << que.top() << endl; } } }
I:区间异或
J:小游戏
这两个待补