Codeforces Round #756 (Div. 3)
A. Make Even
analysis:
Three cases
- Itself is an even number, and the answer is 0
- The highest decimal digit is even, and the answer is 1
- Even numbers exist in non highest decimal places, and the answer is 2
code:
#include <bits/stdc++.h> using namespace std; //#pragma GCC optimize(2) #define close(); ios::sync_with_stdio(false); #define endl '\n' #define rep(i, l, r) for(int i = l; i <= r; i++) #define dwn(i, r, l) for(int i = r; i >= l; i--) typedef long long LL; const int N = 3e5+100; int a[N]; void solve() { LL n; cin >> n; if(n % 2 == 0) cout << 0 << endl; else { int cnt = 0; int x = 0; while(n) { a[++cnt] = n%10; if(a[cnt] % 2 == 0) x = cnt; n/=10; } if(x == 0) cout << "-1" << endl; else { if(x == cnt) cout << 1 << endl; else cout << 2 << endl; } } } int main() { int T; cin >> T; while(T--) solve(); // system("pause"); }
B. Team Composition: Programmers and Mathematicians
analysis:
Obviously, the answer is \ (\ min(\lfloor\frac{a+b}{4}\rfloor, a, b) \)
code:
#include <bits/stdc++.h> using namespace std; //#pragma GCC optimize(2) #define close(); ios::sync_with_stdio(false); #define endl '\n' #define rep(i, l, r) for(int i = l; i <= r; i++) #define dwn(i, r, l) for(int i = r; i >= l; i--) typedef long long LL; const int N = 3e5+100; void solve() { LL a, b; cin >> a >> b; cout << min( (a+b)/4, min(a, b) ) << endl; } int main() { int T; cin >> T; while(T--) solve(); // system("pause"); }
C. Polycarp Recovers the Permutation
analysis:
It is easy to find that the maximum n of array a must appear at both ends of array p
In other words, if n does not exist at both ends of array p, it is illegal
Then we found a construction method:
When constructing array a, put n at one end, so every time you take the element of array p, it is the element at the non-n end
So we only need to flip the array p to get a feasible array a
code:
#include <bits/stdc++.h> using namespace std; //#pragma GCC optimize(2) #define close(); ios::sync_with_stdio(false); #define endl '\n' #define rep(i, l, r) for(int i = l; i <= r; i++) #define dwn(i, r, l) for(int i = r; i >= l; i--) typedef long long LL; const int N = 3e5+100; int a[N]; int b[N]; void solve() { int n; cin >> n; rep(i, 1, n) cin >> a[i]; if(a[1] == n || a[n] == n) { dwn(i, n, 1) cout << a[i] << " "; cout << endl; } else cout << -1 << endl; } int main() { close(); int T; cin >> T; while(T--) solve(); // system("pause"); }
D. Weights Assignment For Tree Edges
analysis:
Firstly, it is easy to find a property. For a given arrangement p, if the parent node of a node is lower than that node, it is obviously illegal
Because obviously, the distance from the parent node to the root node should be smaller
So we can assume that \ (w[fa[i]] \) has been determined when we calculate \ (w[i] \)
Note \ (dis[i] \) indicates the distance from node i to the root node
Therefore, it is not difficult to obtain the equation:
code:
#include <bits/stdc++.h> using namespace std; //#pragma GCC optimize(2) #define close(); ios::sync_with_stdio(false); #define endl '\n' #define rep(i, l, r) for(int i = l; i <= r; i++) #define dwn(i, r, l) for(int i = r; i >= l; i--) typedef long long LL; const int N = 3e5+100; int p[N], to[N]; LL dis[N], w[N]; int b[N]; void solve() { int n; cin >> n; int rt = 0; rep(i, 1, n) dis[i] = w[i] = 0; rep(i, 1, n) { cin >> b[i]; if(b[i] == i) rt = i; } rep(i, 1, n) { cin >> p[i]; to[p[i]] = i; } bool f = 1; if(p[1] != rt) f = 0; else { rep(i, 2, n) { if(to[b[p[i]]] > to[p[i]]) { f = 0; break; } w[p[i]] = dis[p[i-1]] - dis[b[p[i]]] + 1; dis[p[i]] = dis[b[p[i]]] + w[p[i]]; } } if(f == 0) cout << -1 << endl; else rep(i, 1, n) cout << w[i] << " "; cout << endl; } int main() { close(); int T; cin >> T; while(T--) solve(); // system("pause"); }
E1. Escape The Maze (easy version)
analysis:
Note that d[x] represents the closest distance between node X and friend node, and dp[x] represents the depth of node x (that is, the distance from node x to the root node)
It is not difficult to find that node x satisfying \ (dp[x] \ge d[x] \) will be caught by friends and cannot go
So we just need to find out dp and d arrays through dfs again, and then see if we can get to the leaf node
code:
The code is relatively simple. When the game was half played, I was distracted because of autumn promotion
#include <bits/stdc++.h> using namespace std; //#pragma GCC optimize(2) #define close(); ios::sync_with_stdio(false); #define endl '\n' #define rep(i, l, r) for(int i = l; i <= r; i++) #define dwn(i, r, l) for(int i = r; i >= l; i--) typedef long long LL; const int N = 3e5+100; const int INF = 0x3f3f3f3f; vector<int> G[N]; int d[N], dp[N]; void dfs(int x, int fa) { if(x != 1) dp[x] = dp[fa]+1; for(int e: G[x]) { if(e == fa) continue; dfs(e, x); } } void dfs2(int x, int fa) { if(d[x] == 0) return; int t = INF; for(int e: G[x]) { if(e == fa) continue; dfs2(e, x); t = min(t, d[e]); } d[x] = t+1; } bool dfs3(int x, int fa) { if(d[x] <= dp[x]) return 0; if(G[x].size() == 1 && x != 1) return 1; bool f = 0; for(int e: G[x]) { if(e == fa) continue; f |= dfs3(e, x); } return f; } void solve() { int n, k; cin >> n >> k; rep(i, 1, n) dp[i] = 0, d[i] = INF, G[i].clear(); rep(i, 1, k) { int t; cin >> t; d[t] = 0; } rep(i, 1, n-1) { int u, v; cin >> u >> v; G[u].push_back(v); G[v].push_back(u); } dfs(1, 0); dfs2(1, 0); if(dfs3(1, 0)) cout << "YES\n"; else cout << "NO\n"; } int main() { close(); int T; cin >> T; while(T--) solve(); // system("pause"); }
E2. Escape The Maze (hard version)
analysis:
That is, how many nodes are blocked back by the second pass of dfs in E1.
The E1 code can be passed by minor repair
code:
#include <bits/stdc++.h> using namespace std; //#pragma GCC optimize(2) #define close(); ios::sync_with_stdio(false); #define endl '\n' #define rep(i, l, r) for(int i = l; i <= r; i++) #define dwn(i, r, l) for(int i = r; i >= l; i--) typedef long long LL; const int N = 3e5+100; const int INF = 0x3f3f3f3f; vector<int> G[N]; int d[N], dp[N]; int ans = 0; void dfs(int x, int fa) { if(x != 1) dp[x] = dp[fa]+1; for(int e: G[x]) { if(e == fa) continue; dfs(e, x); } } void dfs2(int x, int fa) { if(d[x] == 0) return; int t = INF; for(int e: G[x]) { if(e == fa) continue; dfs2(e, x); t = min(t, d[e]); } d[x] = t+1; } bool dfs3(int x, int fa) { if(d[x] <= dp[x]) { ans++; return 0; } if(G[x].size() == 1 && x != 1) return 1; bool f = 0; for(int e: G[x]) { if(e == fa) continue; f |= dfs3(e, x); } return f; } void solve() { int n, k; cin >> n >> k; rep(i, 1, n) dp[i] = 0, d[i] = INF, G[i].clear(); rep(i, 1, k) { int t; cin >> t; d[t] = 0; } rep(i, 1, n-1) { int u, v; cin >> u >> v; G[u].push_back(v); G[v].push_back(u); } dfs(1, 0); dfs2(1, 0); if(dfs3(1, 0)) cout << -1 << endl; else cout << ans << endl;; ans = 0; } int main() { close(); int T; cin >> T; while(T--) solve(); // system("pause"); }
F. ATM and Students
analysis:
The problem stem requires us to find a longest continuous subsequence to ensure that the sum of all prefixes is not less than k.
Consider the following questions:
Double refers to finding the maximum sum of continuous subsequences for array a (the general algorithm is to discard another stove if the sum of continuous subsequences is less than 0, but a coefficient k should be added here, that is, the sum of continuous subsequences is less than - k.
Then, when solving, we will divide array a into several sets of continuous subsequences, and the prefix sum of each continuous subsequence is not less than k.
Then the answer is the maximum length of these continuous subsequences.
The certificate is as follows:
- If the answer continuous subsequence spans several continuous subsequences, at least one prefix is less than k, which is illegal.
- Obviously, several consecutive subsequences we obtained meet the answer requirements, that is, the sum of all prefixes is not less than k.
note: the big men in the front row seem to use two points Orz
code:
#include <bits/stdc++.h> using namespace std; //#pragma GCC optimize(2) #define close(); ios::sync_with_stdio(false); #define endl '\n' #define rep(i, l, r) for(int i = l; i <= r; i++) #define dwn(i, r, l) for(int i = r; i >= l; i--) typedef long long LL; const int N = 3e5+100; const int INF = 0x3f3f3f3f; LL a[N]; void solve() { int n; LL k; cin >> n >> k; rep(i, 1, n) cin >> a[i]; LL sum = k; int p = 1, q = 1; sum += a[1]; int x, y, cnt; x= y= cnt= 0; while( p <= n && q <= n ) { while(sum >= 0) { if(q-p+1>cnt) { cnt = q-p+1; x = p; y = q; } ++q; if(q > n) break; sum += a[q]; } while(sum < 0) { sum -= a[p]; ++p; if(p > n || p > q) break; } } if(x == y && x == 0) cout << -1 << endl; else cout << x << " " << y << endl; } int main() { close(); int T; cin >> T; while(T--) solve(); // system("pause"); }