Codeforces Round #756 (Div. 3) problem solution A-F

Codeforces Round #756 (Div. 3)

A. Make Even

analysis:

Three cases

  1. Itself is an even number, and the answer is 0
  2. The highest decimal digit is even, and the answer is 1
  3. 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:

The obvious answer is min ⁡ ( ⌊ a + b 4 ⌋ , a , b ) \min(\lfloor\frac{a+b}{4}\rfloor, a, b) min(⌊4a+b​⌋,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 when we calculate w [ i ] w[i] w[i], w [ f a [ i ] ] w[fa[i]] w[fa[i]] is certain

remember d i s [ i ] dis[i] dis[i] represents the distance from node i to the root node

Therefore, it is not difficult to obtain the equation:
w [ p [ i ] ] = d i s [ p [ i − 1 ] ] − d i s [ f a [ p [ i − 1 ] ] ] + 1 ; w[p[i]] = dis[p[i-1]] - dis[fa[p[i-1]]] + 1; w[p[i]]=dis[p[i−1]]−dis[fa[p[i−1]]]+1;

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 for satisfaction d p [ x ] ≥ d [ x ] dp[x] \ge d[x] Node x with dp[x] ≥ d[x] is bound to 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:

  1. If the answer continuous subsequence spans several continuous subsequences, at least one prefix is less than k, which is illegal.
  2. 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");
}

Tags: C Algorithm

Posted on Fri, 26 Nov 2021 05:23:15 -0500 by robin01