The 2020 ICPC Asia Shenyang Regional Programming Contest

1|0D - Journey to Un'Goro


pi表示前缀ir的个数。则题目要求的是prpl1为奇数最多有多少对。显然应该越平均越好。

pi总共有n+1个,则奇偶数的数量均不超过m=n+12,答案就是(n+1m)×m

因此我们可以按照字典序最小进行搜索,并根据m的值进行剪枝。

#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 = 1e9, INF = 1e18; void test() { for (int _ = 1; _ <= 10; _++) { int n = _; vector<vector<int>> ret; int mx = 0; for (int i = 0; i < (1 << n); i++) { vector<int> bit; for (int j = 0; j < n; j++) { if (i >> j & 1) bit.push_back(1); else bit.push_back(0); } int ans = 0; for (int j = 0; j < n; j++) { int cnt = 0; for (int k = j; k < n; k++) { cnt += bit[k]; if (cnt & 1) ans++; } } if (ans > mx) { mx = ans; ret.clear(); } if (ans == mx) ret.push_back(bit); } cout << n << ' '; cout << mx << '\n'; sort(ret.begin(), ret.end()); for (int j = 0; j < ret.size() && j < 100; j++) { cout << j + 1 << " : "; for (int k = 0; k < n; k++) { if (ret[j][k] == 1) cout << 'r'; else cout << 'b'; } cout << '\n'; } } } int cnt = 0, n, m; vector<char> s; void dfs(int i, int x, int y, int t) { // x 为偶数的个数, y 为奇数的个数 if (x > m or y > m) return; if (i == n) { if (x != m and y != m) return; for (auto c: s) cout << c; cout << "\n"; if (++cnt == 100) exit(0); return; } s[i] = 'b'; dfs(i + 1, x + (t == 0), y + (t == 1), t); s[i] = 'r'; dfs(i + 1, x + (t == 1), y + (t == 0), t ^ 1); return; } i32 main() { ios::sync_with_stdio(false), cin.tie(nullptr); cin >> n; m = (n + 2) / 2; cout << m * (n + 1 - m) << "\n"; s.resize(n); dfs(0, 1, 0, 0); return 0; }

2|0F - Kobolds and Catacombs


我们把原序列称为a,排序后称为b。如果序列a,b在区间[l,r]中所有数字出现次数相同,则[l,r]可以被分为一段。

根据这个规则,直接贪心分割就好了。

#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 = 1e9, INF = 1e18; i32 main() { ios::sync_with_stdio(false), cin.tie(nullptr); int n; cin >> n; vi a(n); for (auto &i: a) cin >> i; vi b = a; ranges::sort(b); int res = 0; unordered_map<int, int> cnt; int x = 0, y = 0; for (int i = 0; i < n; i++) { cnt[a[i]]++; if (cnt[a[i]] == 0) y--; if (cnt[a[i]] == 1) x++; cnt[b[i]]--; if (cnt[b[i]] == 0) x--; if (cnt[b[i]] == -1) y++; if (x == 0 and y == 0) res++; } cout << res; return 0; }

3|0G - The Witchwood


#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 = 1e9, INF = 1e18; i32 main() { ios::sync_with_stdio(false), cin.tie(nullptr); int n, k; cin >> n >> k; vi a(n); for (auto &i: a) cin >> i; ranges::sort(a, greater<>()); a.resize(k); i64 sum = 0; for (auto i: a) sum += i; cout << sum; return 0; }

4|0H - The Boomsday Project


我们考虑记录pi×qi次骑车。

比如3条记录

1 2 2 3 3 2

我们就要记录为

1 1 2 2 2 3 3

这样的,假设总共骑车N次,其中第i次骑车的日期为datei

这样的话,我们记状态f[i]表示前i次骑车的最小花费。

我们的转移可以分为两类,第一类是直接购买,f[i]=f[i1]+r

还有一种情况是,我们枚举打折卡(d,k,c),我们找到最早的骑车j,满足datejdateid+1ji+1k,则有转移f[i]=f[j1]+c

当然了这样转移复杂度是O(N2n)

但是我们考虑对于ij一定是单调的。这样的话,我们可以用n个双指针来维护。

#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 = 1e9, INF = 1e18; i32 main() { ios::sync_with_stdio(false), cin.tie(nullptr); int n, m, r; cin >> n >> m >> r; vector<array<int, 3>> a(n); // d day, k free rents, c cost; for (auto &[d, k, c]: a) cin >> d >> k >> c; vi date(1); for (int i = 1, p, q; i <= m; i++) {// p date, q = times; cin >> p >> q; while (q--) date.push_back(p); } ranges::sort(date); int N = date.size() - 1; vi f(N + 1), lst(n, 1); for (int i = 1; i <= N; i++) { f[i] = f[i - 1] + r; for (int j = 0; j < n; j++) { const auto &[d, k, c] = a[j]; while (date[lst[j]] < date[i] - d + 1 or lst[j] < i + 1 - k) lst[j]++; f[i] = min(f[i], f[lst[j] - 1] + c); } } cout << f[N] << "\n"; return 0; }

5|0I - Rise of Shadows


首先分针的转速w1=2πM,时针的转速w2=2πHM,在经过T分钟后的角度差为

Δθ=T(w1w2)mod2π=T(2πM2πHM)mod2π=T2πHM(H1)mod2π

根据题目要求得到不等式

Δθ2πAMHT2πHM(H1)mod2π2πAHMT(H1)modHMA

和不等式

2πΔθ2πAHMΔθ2π2πAHMT2πHM(H1)mod2π2π2πAHMT(H1)modHMHMA

d=gcd(H1,HM),根据

ABCACBABCACB

可以得到

T(H1)dmodHMdAdT(H1)dmodHMdHMAd

对于左侧,因为H1d,HMd互质,因此左侧整个的取值为[0,HMd)

对于右侧,根据题目已知条件AHM2可以得到

Ad<HMdHMAd<HMd

因此对于第一个不等式左侧的合法取值范围是[0,Ad],第二个不等式合法取值范围是[HMAd,HMd)

所以解的个数就是

Ad+1+HMdHMAd

特别的当A==HMA在等号处会计算重复,此时的解的个数为HMd

当然了以上的计算,可以认为是一轮。一共进行的d轮,所以最终的答案还要乘d

#include <bits/stdc++.h> using namespace std; using i32 = int32_t; using i64 = long long; #define int i64 using vi = vector<int>; using pii = pair<int, int>; const int inf = LLONG_MAX / 2; i32 main() { int H, M, A; cin >> H >> M >> A; int HM = H * M; int d = gcd(H - 1, HM); if (HM == A * 2) { cout << HM; } else { cout << (A / d + 1 + HM / d - (HM - A + d - 1) / d) * d; } return 0; }

6|0K - Scholomance Academy


关于题目难点是理解题目。

记真的阳性数为Positive,阴性数为Negative,则有Positive=TP+FN,Negative=TN+FP

这样的话TPR,FPR实际上都是只有一个变量。然后再看这个积分,实际上就是样例里面的图的面积。

这个图怎么来的?实际上就是根据坐标点(TPR,FPR)连成一个折线图。

而积分的值就是tpPositive×1Negative

然后我们考虑初始的θ=0,此时TPR=1,FPR=0。然后把所有的instances按照score排序,然后初始的tp=Positive,然后如果这个type为阳性,这说明随着θ增大这个阳性要被错误的估计,所以tp —。否则的话,说明FPR会发生改变,此时产生了新的值,因此我们要记录一下当前的答案tpPositive×1Negative

#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 = 1e9, INF = 1e18; struct instance { bool type; int score; bool operator<(instance &b) const { if (score != b.score) return score < b.score; return type > b.type; } }; i32 main() { ios::sync_with_stdio(false), cin.tie(nullptr); int n, positive = 0, negative = 0; cin >> n; vector<instance> a(n); for (char c; auto &it: a) { cin >> c >> it.score; it.type = (c == '+'); if (it.type) positive++; else negative++; } sort(a.begin(), a.end()); int tp = positive, res = 0; for (auto it: a) { if (it.type) tp--; else res += tp; } cout << fixed << setprecision(20) << (long double) res / (long double) (positive * negative); return 0; }

__EOF__

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