ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

Codeforces Round #756 (Div. 3)题解A-F

2021-11-26 14:33:44  阅读:226  来源: 互联网

标签:fa int 题解 rep Codeforces long -- Div define


Codeforces Round #756 (Div. 3)

A. Make Even

分析:

三种情况

  1. 本身是偶数, 答案为0
  2. 十进制最高位是偶数, 答案为1
  3. 十进制非最高位存在偶数, 答案为2

代码:

#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

分析:

显然答案是\(\min(\lfloor\frac{a+b}{4}\rfloor, a, b)\)

代码:

#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

分析:

容易发现数组a的最大值n, 一定出现在p数组的两端.

也就是说如果如果数组p的两端不存在n, 那么就是不合法的.

然后我们发现了一种构造做法:

在构造数组a的时候, 把n放在一端, 那么每次拿去构造数组p的元素都是在非n端的元素.

于是只需要把数组p翻转即可得到一种可行的数组a.

代码:

#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

分析:

首先容易发现一个性质, 对于给定的排列p, 如果存在某个节点的父节点比该节点排名靠后, 那么显然是不合法的.

因为显然父节点到根节点的距离应该更小.

所以我们可以假设当我们计算\(w[i]\)时, \(w[fa[i]]\)是已经确定了的.

记\(dis[i]\)表示节点i到根节点的距离.

于是不难得到方程:

\[w[p[i]] = dis[p[i-1]] - dis[fa[p[i-1]]] + 1; \]

代码:

#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)

分析:

记d[x]表示节点x距离朋友节点的最近距离, dp[x]表示节点x的深度(即节点x到根节点的距离).

不难发现, 对于满足\(dp[x] \ge d[x]\)的节点x, 是一定会被朋友抓的, 是不可走的.

于是我们只需要一遍dfs求出dp和d数组, 然后再dfs一遍看看能不能走到叶节点即可.

代码:

代码比较憨, 比赛打一半的时候因为秋促场外走神了.

#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)

分析:

就是问说E1里第二遍dfs的时候,被多少个不可走的节点挡回了。

把E1的代码小修小补一下就能过了

代码:

#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

分析:

题干要求我们求出一个最长连续子序列保证其中所有的前缀和不小于k。

考虑讲问题转化如下:

双指针对数组a求最大连续子序列和(一般算法是如果连续子序列和小于0就弃掉另起炉灶,但是这里要加个系数k,即连续子序列和小于-k才弃掉另起炉灶)。

然后求的时候我们会把数组a分成几个连续子序列的集合,每个连续子序列的前缀和都不小于k。

那么答案就是这些连续子序列的最大长度。

证明如下:

  1. 如果答案连续子序列是横跨若干个我们求出来的连续子序列的,那么至少存在一个前缀小于-k,即不合法。
  2. 显然我们求出的若干个连续子序列都符合答案要求, 即所有前缀和不小于-k。

note: 前排大佬好像都用的二分Orz

代码:

#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");
}

标签:fa,int,题解,rep,Codeforces,long,--,Div,define
来源: https://www.cnblogs.com/Arctic-Lab/p/15607640.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有