A. Direction Change通过镜像翻折,将目标点翻折到主对角线上
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 #include <bits/stdc++.h> void solve () { int n,m; std::cin >> n >> m; int ans; if (n == 1 ) { if (m <= 2 ) ans = m - 1 ; else ans = -1 ; } else if (m == 1 ) { if (n <= 2 ) ans = n - 1 ; else ans = -1 ; } else { while (n + 2 <= m) n += 2 ; while (m + 2 <= n) m += 2 ; ans = m + n - 2 ; } std::cout << ans << '\n' ; } int main () {}
B. Social Distance 将 相近的点放在相邻位置,尽可能的让不可选位置重叠
注意数据范围 long long
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 #include <bits/stdc++.h> bool solve () { int n,m; std::cin >> n >> m; std::vector<int > a (n) ; for (int i = 0 ; i < n; i++) std::cin >> a[i]; sort (a.begin (), a.end ()); long long pos = 1 ; for (int i = 0 ; i + 1 < n; i++) { pos = pos + std::max (a[i],a[i + 1 ]) + 1 ; if (pos > m) return false ; } if (pos > m || (m - pos) < std::max (a[0 ],a[n - 1 ])) return false ; return true ; } int main () {}
C. Make it Increasing 最优情况下,一定能确定有一个点的值没有改变
枚举值没改变的点
注意数据范围 long long
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 #include <bits/stdc++.h> #define LL long long void solve () { int n; std::cin >> n; std::vector<LL> a (n) ; for (int i = 0 ; i < n; i++) std::cin >> a[i]; LL ans = 1e17 + 7 ; for (int i = 0 ; i < n; i++) { LL sum = 0 ,now; now = 0 ; for (int j = i - 1 ; j >= 0 ; j--) { LL k = now / a[j]; if (k * a[j] <= now) k++; now = a[j] * k; sum += k; } now = 0 ; for (int j = i + 1 ; j < n; j++) { LL k = now / a[j]; if (k * a[j] <= now) k++; now = a[j] * k; sum += k; } ans = std::min (ans,sum); } std::cout << ans << '\n' ; } int main () {}
D. Optimal Partition 不难想到 复杂度的 转移方程
考虑使用数据结构优化
对于第 个点,对它有贡献的 满足 , ,考虑将 单独列出去,则原方程变为在某个区间里找最大的
发现这是二维逆序,维护下标 递增,通过 实现前缀区间最大值查询
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 #include <bits/stdc++.h> #define LL long long std::vector<int > a,f,hash,ans; std::vector<long long > prefix; std::vector<std::pair<long long ,int >> g; int lowbit (int x) { return x & -x; } void add (int pos,int val) { int n = f.size () - 1 ; for (int x = pos; x <= n; x += lowbit (x)) f[x] = std::max (f[x],val); } int ask (int pos) { int val = -1e7 ; for (int x = pos; x > 0 ; x -= lowbit (x)) val = std::max (val,f[x]); return val; } void init (int n) { a.clear ();a.resize (n + 1 ); ans.clear ();ans.resize (n + 1 ); f.clear ();f.resize (n + 1 ,-1e7 ); hash.clear ();hash.resize (n + 1 ); prefix.clear ();prefix.resize (n + 1 ); g.clear ();g.resize (n); } void solve () { int n; std::cin >> n; init (n); for (int i = 1 ; i <= n; i++) { std::cin >> a[i]; prefix[i] = prefix[i - 1 ] + a[i]; g[i - 1 ] = std::make_pair (prefix[i],-i); } std::sort (g.begin (), g.end ()); for (int i = 0 ; i < n; i++) hash[-g[i].second] = i + 1 ; for (int i = 1 ; i <= n; i++) { ans[i] = ans[i - 1 ] + ((a[i] > 0 ) ? 1 : (a[i] < 0 ) ? -1 : 0 ); ans[i] = std::max (ans[i],ask (hash[i] - 1 ) + i); if (prefix[i] > 0 ) ans[i] = i; add (hash[i],ans[i] - i); } std::cout << ans[n] << '\n' ; } int main () {}
E. Half Queen Cover 比赛时想了很多乱七八糟的方法,赛后又想了一个多小时
感觉应该是将 按能否整除 分开讨论
整除 时,会有一个点在主对角线上,负责占领边界上的那两个点,然后转移到 的状态
不整除 时,考虑递推的方式,开始是 ,然后是 (横纵坐标分别加 ),然后是 ,后边还没推出来。。。
有空去研究下题解
F. Edge Elimination 挖坑
总结 & 吐槽 Rating 变化:
表现分:
Rank:
题在一些奇怪的地方卡住了,花了接近十分钟
题 题比较显然,但有点着急,交之前没注意数据范围, 了三次
题 没想出来,想了二三十分钟就去想 了。式子里面将 单列出去的手法以前有见过,但比赛时没想起来。。。得练练 了
题构造没想出来
总的来说,这场表现不是很好, 了三次导致得分少了 ,如果没有 的话,这次说不定能上一两分?
还得加练QAQ
这两周课程有丶多,然后期中考一堆。。。
后面几场 可能不会打了,等有空再去 一下,希望不要是送分场,我会心态裂开的