Codeforces Round #353 (Div. 2)
Posted Running_Time
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Codeforces Round #353 (Div. 2)相关的知识,希望对你有一定的参考价值。
等差数列,公差是0的时候特判
#include <bits/stdc++.h> typedef long long ll; const int N = 1e5 + 5; int main() { int a, b, c; scanf ("%d%d%d", &a, &b, &c); bool flag = true; if (c == 0) { if (a == b) { flag = true; } else { flag = false; } } else { int d = (b - a) / c; if (d >= 0 && (b - a) % c == 0) { flag = true; } else { flag = false; } } if (flag) { puts ("YES"); } else { puts ("NO"); } return 0; }
题意:3*3的矩阵,已经填了a,b,c,d四个数字,问填完数后四个2*2的子矩阵的和相等的方案数,所有数字范围在[1, n].
分析:蛮有意思的题目,很明显中心的数字是公有的,?从上到下从左到右设为x1,x2,x3,x4x5,那么满足x1+a+b=x4+b+d -> x4 = x1 + (a - d),x2=x1+(b-c), x5=x1+(a+b-c-d),因为x2, x4, x5范围在[1, n],能得到一个x1的最小可行区间,然后*x3的可行区间(n).当然O(n)枚举也可以.
#include <bits/stdc++.h> typedef long long ll; const int N = 1e5 + 5; int main() { int n, a, b, c, d; scanf ("%d%d%d%d%d", &n, &a, &b, &c, &d); int d1 = a - d, d2 = b - c, d3 = a + b - c - d; int l = 1, r = n; l = std::max (l, 1 - d1); r = std::min (r, n - d1); l = std::max (l, 1 - d2); r = std::min (r, n - d2); l = std::max (l, 1 - d3); r = std::min (r, n - d3); if (l <= r) { long long ans = 1ll * (r - l + 1) * n; std::cout << ans << ‘\n‘; } else { puts ("0"); } return 0; }
题意:n个数字有正有负,总和0,相邻数字可以分配,问最小操作数使得所有数字变成0.
分析:如果一段长度为L数字总和为0,最多L-1次可以使得每个数字为0.将n个数字分成m段都是0的,那么答案是n-m,所以求cnt[k]最大,表示m最大(最后一组为-k+k).
#include <bits/stdc++.h> int main() { std::ios::sync_with_stdio (false); std::cin.tie (0); std::map<long long, int> mp; int n; std::cin >> n; long long sum = 0; int mx = 0; for (int i=0; i<n; ++i) { int x; std::cin >> x; sum += x; mp[sum]++; mx = std::max (mx, mp[sum]); } std::cout << n - mx << ‘\n‘; return 0; }
题意:按照BST建一棵树二叉树,问当前插入的点的父节点.
分析:set模拟平衡树,lower_bound查找位置.
#include <bits/stdc++.h> const int N = 1e5 + 5; std::set<int> st; std::map<int, int> left, right; int main() { int n, x; scanf ("%d", &n); scanf ("%d", &x); st.insert (x); int ans; for (int i=0; i<n-1; ++i) { scanf ("%d", &x); auto it = st.lower_bound (x); if (it != st.end () && left.count (*it) == 0) { left[*it] = x; ans = *it; } else { --it; right[*it] = x; ans = *it; } st.insert (x); printf ("%d ", ans); } return 0; }
题意:第i个车站能到[i+1, a[i]]的位置,p(i, j)表示从i到j最少搭几次车.求
分析:定义dp[i]表示的最小搭车数,从[i+1, n]中a[m]最大的dp[m]转移来,...
#include <bits/stdc++.h> const int N = 1e5 + 5; int a[N]; long long dp[N]; std::pair<int, int> mx[N][20]; int n; void init_ST() { for (int i=0; i<n; ++i) { mx[i][0] = {a[i], i}; } for (int j=1; (1<<j)<=n; ++j) { for (int i=0; i+(1<<j)-1<n; ++i) { mx[i][j] = std::max (mx[i][j-1], mx[i+(1<<(j-1))][j-1]); } } } int query_max(int l, int r) { int k = 0; while (1<<(k+1) <= r - l + 1) k++; return std::max (mx[l][k], mx[r-(1<<k)+1][k]).second; } int main() { scanf ("%d", &n); a[n-1] = n - 1; for (int i=0; i<n-1; ++i) { scanf ("%d", a+i); a[i]--; } init_ST (); long long ans = 0; dp[n-1] = 0; for (int i=n-2; i>=0; --i) { int p = query_max (i + 1, a[i]); dp[i] = dp[p] - (a[i] - p) + n - i - 1; ans += dp[i]; } printf ("%I64d\n", ans); return 0; }
以上是关于Codeforces Round #353 (Div. 2)的主要内容,如果未能解决你的问题,请参考以下文章
Codeforces Round #353 (Div. 2) A. Infinite Sequence
[Codeforces] Round #353 (Div. 2)
Codeforces Round #353 (Div. 2) A. Infinite Sequence 思维题
Codeforces Round #353 (Div. 2) ABCDE 题解 python
Codeforces Round #353 (Div. 2)
Codeforces Round #353 (Div. 2) B. Restoring Painting __ map or set 思维题