Codeforces Round #805 (Div. 3)

Codeforces Round #805 (Div. 3)

Dashboard - Codeforces Round #805 (Div. 3) - Codeforces

A

Problem - A - Codeforces

减去10^(位数-1)就是答案

// Problem: A. Round Down the Price
// Contest: Codeforces - Codeforces Round #805 (Div. 3)
// URL: https://codeforces.com/contest/1702/problem/A
// Memory Limit: 256 MB
// Time Limit: 1000 ms
//
// Powered by CP Editor (https://cpeditor.org)

#include <bits/stdc++.h>
using namespace std;

typedef long long ll;

int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    int t;
    cin >> t;
    while (t--)
    {
        string m;
        cin >> m;
        int res = atoi(m.c_str()) - pow(10, m.size() - 1);
        cout << res << endl;
    }
    return 0;
}

B

Problem - B - Codeforces

模拟,一天记3个字符,如果碰到第四个就记作第二天

// Problem: B. Polycarp Writes a String from Memory
// Contest: Codeforces - Codeforces Round #805 (Div. 3)
// URL: https://codeforces.com/contest/1702/problem/B
// Memory Limit: 256 MB
// Time Limit: 2000 ms
//
// Powered by CP Editor (https://cpeditor.org)

#include <bits/stdc++.h>
using namespace std;

typedef long long ll;

int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    int t;
    cin >> t;
    while (t--)
    {
        string s;
        cin >> s;
        int ans = 1;
        char a[3];
        int cnt = 0;
        for (int i = 0; i < s.size(); i++)
        {
            bool flag = false;
            for (int j = 0; j < cnt; j++)
            {
                if (s[i] == a[j])
                    flag = true;
            }
            if (flag)
                continue;
            else if (cnt <= 2)
            {
                a[cnt++] = s[i];
            }
            else
            {
                ans++;
                cnt = 0;
                a[cnt++] = s[i];
            }
        }
        cout << ans << endl;
    }
    return 0;
}

C

Problem - C - Codeforces

记录每个站的第一次出现位置和最后一次出现位置,对于每个询问a和b,如果b出现的最后一次在a第一次出现的右边,则能够到达

// Problem: C. Train and Queries
// Contest: Codeforces - Codeforces Round #805 (Div. 3)
// URL: https://codeforces.com/contest/1702/problem/C
// Memory Limit: 256 MB
// Time Limit: 3000 ms
//
// Powered by CP Editor (https://cpeditor.org)

#include <bits/stdc++.h>
using namespace std;

typedef long long ll;

int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    int t;
    cin >> t;

    while (t--)
    {
        map<int, int> m, m1, m2;
        int n, k;
        cin >> n >> k;
        for (int i = 0; i < n; i++)
        {
            int x;
            cin >> x;
            m[x] = 1;
            if (m1[x] == 0)
                m1[x] = i + 1;
            m2[x] = i + 1;
        }
        for (int i = 0; i < k; i++)
        {
            int a, b;
            cin >> a >> b;
            if (!m[a] || !m[b])
            {
                cout << "NO" << endl;
                continue;
            }

            if (m2[b] > m1[a])
                cout << "YES" << endl;
            else
                cout << "NO" << endl;
        }
    }
    return 0;
}

D

Problem - D - Codeforces

贪心,选价值最大的删除

// Problem: D. Not a Cheap String
// Contest: Codeforces - Codeforces Round #805 (Div. 3)
// URL: https://codeforces.com/contest/1702/problem/D
// Memory Limit: 256 MB
// Time Limit: 2000 ms
//
// Powered by CP Editor (https://cpeditor.org)
#include <bits/stdc++.h>
using namespace std;

typedef long long ll;

int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    int t;
    cin >> t;
    while (t--)
    {
        string s;
        cin >> s;
        int p;
        cin >> p;
        vector<int> pos[26];
        int sum = 0;
        for (int i = 0; i < s.size(); i++)
        {
            pos[s[i] - 'a'].push_back(i);
            sum += (s[i] - 'a' + 1);
        }
        int tail = 25;
        while (sum > p)
        {
            while (pos[tail].empty())
                tail--;
            pos[tail].pop_back();
            sum -= (tail + 1);
        }
        vector<pair<int, char>> v;
        for (int i = 0; i < 26; i++)
        {
            for (auto j : pos[i])
            {
                v.push_back({j, 'a' + i});
            }
        }
        sort(v.begin(), v.end());
        for (auto i : v)
        {
            cout << i.second;
        }
        cout << endl;
    }
    return 0;
}

E

Problem - E - Codeforces

带权并查集

参考:Codeforces Round #805 (Div. 3) A - G - 知乎 (zhihu.com)

// Problem: E. Split Into Two Sets
// Contest: Codeforces - Codeforces Round #805 (Div. 3)
// URL: https://codeforces.com/contest/1702/problem/E
// Memory Limit: 256 MB
// Time Limit: 2000 ms
//
// Powered by CP Editor (https://cpeditor.org)

#include <bits/stdc++.h>
using namespace std;

typedef long long ll;

const int maxn = 2e5 + 5, INF = 0x3f3f3f3f;
int p[maxn * 2];
vector<int> g[maxn];

int find(int x)
{
    if (p[x] != x)
    {
        p[x] = find(p[x]);
    }
    return p[x];
}

void merge(int x, int y)
{
    int px = find(x), py = find(y);
    if (px != py)
        p[px] = py;
}

int main()
{

    cin.tie(0);
    cout.tie(0);
    ios::sync_with_stdio(0);

    int T;
    cin >> T;
    while (T--)
    {
        int n;
        cin >> n;
        for (int i = 1; i <= n; i++)
            g[i].clear();
        for (int i = 1; i <= 2 * n; i++)
            p[i] = i;
        bool success = 1;
        for (int i = 1; i <= n; i++)
        {
            int a, b;
            cin >> a >> b;
            if (a == b)
                success = 0;
            if (g[a].size() >= 2 || g[b].size() >= 2)
                success = 0;
            if (g[a].size() && g[b].size())
            {
                int pa = find(g[a][0]), pb = find(g[b][0] + n);
                if (pa == pb)
                    success = 0;
            }
            if (g[a].size())
                merge(i, g[a][0] + n), merge(i + n, g[a][0]);
            if (g[b].size())
                merge(i, g[b][0] + n), merge(i + n, g[b][0]);
            g[a].push_back(i);
            g[b].push_back(i);
        }
        cout << (success ? "YES" : "NO") << '\n';
    }
}

F

Problem - F - Codeforces

优先队列,

对b乘2相当于对a除2,但只有a为偶数才能操作,

找两个序列中的最大值,如果相同,那么可以凑成一对相同的数,

如果不同,则对较大的数除2,但是a只有为偶数是才可除二,如为奇数则一定无法成功,

如此操作直至队列为空

// Problem: F. Equate Multisets
// Contest: Codeforces - Codeforces Round #805 (Div. 3)
// URL: https://codeforces.com/contest/1702/problem/F
// Memory Limit: 256 MB
// Time Limit: 4000 ms
//
// Powered by CP Editor (https://cpeditor.org)

#include <bits/stdc++.h>
using namespace std;

typedef long long ll;

priority_queue<int> a, b;

void solve()
{
    priority_queue<int> a, b;
    int n;
    cin >> n;
    for (int i = 0; i < n; i++)
    {
        int x;
        cin >> x;
        b.push(x);
    }
    for (int i = 0; i < n; i++)
    {
        int x;
        cin >> x;
        a.push(x);
    }
    int res = 0;
    while (!a.empty())
    {
        int t1 = a.top(), t2 = b.top();
        if (t1 == t2)
        {
            a.pop();
            b.pop();
        }
        else if (t1 > t2)
        {
            a.pop();
            a.push(t1 / 2);
            res++;
        }
        else
        {
            if (t2 % 2)
            {
                cout << "NO" << endl;
                return;
            }
            b.pop();
            b.push(t2 / 2);
            res++;
        }
    }
    cout << "YES" << endl;
}

int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    int t;
    cin >> t;
    while (t--)
    {
        solve();
    }
    return 0;
}

G

Problem - G1 - Codeforces

LCA,参考:Codeforces Round #805 (Div. 3) A - G - 知乎 (zhihu.com)

首先假设这条链的两个端点是\(p1\)\(p2\),假设某个点\(p\)\(p1\)\(p2\)为端点的链上,我们分别计算\(p\)与两个端点的最近公共祖先lca,这两个lca一定一个是\(p\)本身,另一个是\(p1\)\(p2\)的lca,所以我们的做法就是找到链的两个端点,然后判断其他点是不是在链上就行了.

那么如何确定链的两个端点呢?第一个端点\(p1\)可以用深度最大的点,第二个端点可以找和\(p1\)不在同一个子树(即\(lca(p1,p)!=p\))里的深度最大的点.

// Problem: G1. Passable Paths (easy version)
// Contest: Codeforces - Codeforces Round #805 (Div. 3)
// URL: https://codeforces.com/contest/1702/problem/G1
// Memory Limit: 256 MB
// Time Limit: 2000 ms
//
// Powered by CP Editor (https://cpeditor.org)

#include <bits/stdc++.h>
using namespace std;

typedef long long ll;

const int maxn = 2e5 + 5, maxm = maxn * 2, INF = 0x3f3f3f3f;
int h[maxn], e[maxm], ne[maxm], idx;
int d[maxn], q[maxn], fa[maxn][20], p[maxn];

void add(int a, int b)
{
    e[idx] = b, ne[idx] = h[a], h[a] = idx++;
}

void bfs()
{
    d[1] = 1;
    int hh = 0, tt = -1;
    q[++tt] = 1;
    while (hh <= tt)
    {
        int t = q[hh++];
        for (int i = h[t]; ~i; i = ne[i])
        {
            int j = e[i];
            if (!d[j])
            {
                d[j] = d[t] + 1;
                q[++tt] = j;
                fa[j][0] = t;
                for (int k = 1; k <= 19; k++)
                    fa[j][k] = fa[fa[j][k - 1]][k - 1];
            }
        }
    }
}

int lca(int a, int b)
{
    if (d[a] < d[b])
        swap(a, b);
    for (int i = 19; i >= 0; i--)
        if (d[fa[a][i]] >= d[b])
            a = fa[a][i];
    if (a == b)
        return a;
    for (int i = 19; i >= 0; i--)
        if (fa[a][i] != fa[b][i])
            a = fa[a][i], b = fa[b][i];
    return fa[a][0];
}

int main()
{

    cin.tie(0);
    cout.tie(0);
    ios::sync_with_stdio(0);

    memset(h, -1, sizeof h);
    int n, m;
    cin >> n;
    for (int i = 0; i < n - 1; i++)
    {
        int a, b;
        cin >> a >> b;
        add(a, b), add(b, a);
    }
    bfs();
    cin >> m;
    while (m--)
    {
        int cnt;
        cin >> cnt;
        int p1 = -1, p2 = -1;
        for (int i = 0; i < cnt; i++)
        {
            cin >> p[i];
            if (p1 == -1 || d[p[i]] > d[p1])
                p1 = p[i];
        }
        for (int i = 0; i < cnt; i++)
        {
            if (p[i] != p1)
            {
                int anc = lca(p1, p[i]);
                if (anc != p[i])
                {
                    if (p2 == -1 || d[p[i]] > d[p2])
                        p2 = p[i];
                }
            }
        }
        if (p2 == -1)
            cout << "YES" << '\n';
        else
        {
            int anc = lca(p1, p2);
            bool success = 1;
            for (int i = 0; i < cnt; i++)
            {
                int anc1 = lca(p1, p[i]);
                int anc2 = lca(p2, p[i]);
                if (!((anc1 == p[i] && anc2 == anc) || (anc2 == p[i] && anc1 == anc)))
                {
                    success = 0;
                    break;
                }
            }
            cout << (success ? "YES" : "NO") << '\n';
        }
    }
}

posted @ 2022-07-11 16:06  扶木  阅读(497)  评论(0)    收藏  举报