"Wdoi2021" Windy OI Codeforces Round 1 Summary

T1 Beautiful Array

Question meaning: try to divide a bracket string of length n into 2m subsequences. The subsequence can be empty, and each character must be divided into exactly one subsequence. Make at least m subsequences a matching string of parentheses. An empty sequence is not a matching sequence of parentheses. If there is no solution, please output 0, otherwise output 1. There are multiple groups of data in this question, of which the number of data groups is t. A is defined as a subsequence of B if and only if a can be obtained by B deleting several elements without changing the order\ (1\leq T,n,m \leq 200\)

Check in question. Because the data is very small, you can find the possible matching bracket string and compare it with m

#include <iostream>
#include <cstdio>
using namespace std;
const int N = 250;
int T, n, m;
string s;
int vis[N];
int main()
{
    ios::sync_with_stdio(false);
    int T;
    cin >> T;
    while (T--)
    {
        cin >> n >> m;
        cin >> s;
        s = ' ' + s;
        for (int i = 1; i <= n; i++)
            vis[i] = 0;
        int cnt = 0;
        for (int i = 1; i <= n; i++)
        {
            if (vis[i])
                continue;
            if (s[i] == '(')
                for (int j = i + 1; j <= n; j++)
                    if (s[j] == ')' && !vis[j])
                    {
                        vis[i] = 1, vis[j] = 1, cnt++;
                        break;
                    }
            if (s[i] == ')')
                for (int j = 1; j <= i - 1; j++)
                    if (s[j] == '(' && !vis[j])
                    {
                        vis[i] = 1, vis[j] = 1, cnt++;
                        break;
                    }
        }
        if (cnt >= m)
            cout << 1 << endl;
        else
            cout << 0 << endl;
    }
}

T2 Alice Wins! (easy version)

AB 2n people in each team are playing with stone, scissors and paper. The \ (I \) of team A pays $a_i $, team B \ (I \) out \ (b_i \). People with the same number will fight. If team A wins, one point will be added, no point will be scored, and one point will be deducted if team A loses. You can change the boxing scheme of \ (n \) individuals in each team at most to make team A score the highest. The maximum value of the output score and any set of construction schemes.

In this question, we use 1 for stone, 2 for scissors and 3 for cloth.

Check in question. It is easy to find that in the worst case, it only needs n times on one side to change to win all, so sweep it and directly change it to win all. Be careful not to change one side more than n times

#include <iostream>
#include <cstdio>
using namespace std;
const int N = 500005;
int n;
int cmp(int a, int b)
{
    if (a == b)
        return 0;
    if (a != 1 && b != 1)
    {
        if (a < b)
            return 1;
        if (a > b)
            return -1;
    }
    if (a == 1)
    {
        if (b == 2)
            return 1;
        if (b == 3)
            return -1;
    }
    if (b == 1)
    {
        if (a == 2)
            return -1;
        if (a == 3)
            return 1;
    }
}
int a[N], b[N];
int cnt;
int main()
{
    ios::sync_with_stdio(false);
    int T;
    cin >> T;
    while (T--)
    {
        cin >> n;
        for (int i = 1; i <= 2 * n; i++)
            cin >> a[i];
        for (int i = 1; i <= 2 * n; i++)
            cin >> b[i];
        cnt = 0;
        for (int i = 1; i <= 2 * n; i++)
            if (cmp(a[i], b[i]) == -1 && cnt < n)
            {
                cnt++, a[i]++;
                if (a[i] == 4)
                    a[i] = 1;
            }
        for (int i = 1; i <= 2 * n; i++)
            if (cmp(a[i], b[i]) == 0 && cnt < n)
            {
                cnt++, a[i]--;
                if (a[i] == 0)
                    a[i] = 3;
            }
        cnt = 0;
        for (int i = 1; i <= 2 * n; i++)
            if (cmp(a[i], b[i]) == -1 && cnt < n)
            {
                cnt++, b[i]--;
                if (b[i] == 0)
                    b[i] = 3;
            }
        for (int i = 1; i <= 2 * n; i++)
            if (cmp(a[i], b[i]) == 0 && cnt < n)
            {
                cnt++, b[i]++;
                if (b[i] == 4)
                    b[i] = 1;
            }
        int sum = 0;
        for (int i = 1; i <= 2 * n; i++)
            sum += cmp(a[i], b[i]);
        cout << sum << endl;
        for (int i = 1; i <= 2 * n; i++)
            cout << a[i] << " ";
        cout << endl;
        for (int i = 1; i <= 2 * n; i++)
            cout << b[i] << " ";
        cout << endl;
    }
}

T3 Alice Wins! (hard version)

The same as T2, but change it exactly n times on each side

After a little thought, it is easy to find that we only need to solve how to waste the number of times after completely winning. Obviously, for the position that has not been changed, that is, the position that has already won, we can waste two operations up and down at the same time + 1 / - 1. In this way, because one of the remaining two sides of the parity is modified, we only need to change the position that has been changed to win from changing one side to win to changing both sides to win

It has a large code size and more details, but it is not too difficult

#include <iostream>
#include <cstdio>
#include <assert.h>
using namespace std;
const int N = 500005;
int n;
int cmp(int a, int b)
{
    if (a == b)
        return 0;
    if (a != 1 && b != 1)
    {
        if (a < b)
            return 1;
        if (a > b)
            return -1;
    }
    if (a == 1)
    {
        if (b == 2)
            return 1;
        if (b == 3)
            return -1;
    }
    if (b == 1)
    {
        if (a == 2)
            return -1;
        if (a == 3)
            return 1;
    }
}
int a[N], b[N], arta[N], artb[N], ta[N], tb[N];
int cnta, cntb, cntfail, cntdraw;
int main()
{
    ios::sync_with_stdio(false);
    int T;
    cin >> T;
    while (T--)
    {
        cin >> n;
        cntdraw = 0, cntfail = 0, cnta = 0, cntb = 0;
        for (int i = 1; i <= 2 * n; i++)
            arta[i] = 0, artb[i] = 0;
        for (int i = 1; i <= 2 * n; i++)
        {
            cin >> a[i];
            ta[i] = a[i];
        }
        for (int i = 1; i <= 2 * n; i++)
        {
            cin >> b[i];
            tb[i] = b[i];
        }
        for (int i = 1; i <= 2 * n; i++)
        {
            if (cmp(a[i], b[i]) == -1)
                cntfail++;
            if (cmp(a[i], b[i]) == 0)
                cntdraw++;
        }
        if (cntfail % 2 == 1)
            cntfail++;
        for (int i = 1; i <= 2 * n; i++)
            if (cmp(a[i], b[i]) == -1 && cnta < cntfail / 2)
            {
                cnta++;
                a[i]++;
                if (a[i] == 4)
                    a[i] = 1;
                arta[i] = 1;
            }
        for (int i = 1; i <= 2 * n; i++)
            if (cmp(a[i], b[i]) == -1 && cntb < cntfail / 2)
            {
                cntb++;
                b[i]--;
                if (b[i] == 0)
                    b[i] = 3;
                artb[i] = 1;
            }
        int sa = cnta, sb = cntb;
        if (cntdraw % 2 == 1)
            cntdraw++;
        for (int i = 1; i <= 2 * n; i++)
            if (cmp(a[i], b[i]) == 0 && cntb - sb < cntdraw / 2)
            {
                cntb++;
                b[i]++;
                if (b[i] == 4)
                    b[i] = 1;
                artb[i] = 1;
            }
        for (int i = 1; i <= 2 * n; i++)
            if (cmp(a[i], b[i]) == 0 && cnta - sa < cntdraw / 2)
            {
                cnta++;
                a[i]--;
                if (a[i] == 0)
                    a[i] = 3;
                arta[i] = 1;
            }
        for (int i = 1; i <= 2 * n; i++)
            if (cmp(a[i], b[i]) == 1 && !(arta[i] || artb[i]) && cnta < n && cntb < n)
            {
                cnta++, cntb++;
                a[i]++, b[i]++;
                if (a[i] == 4)
                    a[i] = 1;
                if (b[i] == 4)
                    b[i] = 1;
            }
        if (cnta != n)
            for (int i = 1; i <= 2 * n; i++)
                if (cmp(a[i], b[i]) == 1 && artb[i] && cnta < n)
                {
                    cnta++;
                    a[i]++, b[i]++;
                    if (a[i] == 4)
                        a[i] = 1;
                    if (b[i] == 4)
                        b[i] = 1;
                    if (b[i] == tb[i])
                    {
                        a[i]++, b[i]++;
                        if (a[i] == 4)
                            a[i] = 1;
                        if (b[i] == 4)
                            b[i] = 1;
                    }
                    break;
                }
        if (cntb != n)
            for (int i = 1; i <= 2 * n; i++)
                if (cmp(a[i], b[i]) == 1 && arta[i] && cntb < n)
                {
                    cntb++;
                    a[i]++, b[i]++;
                    if (a[i] == 4)
                        a[i] = 1;
                    if (b[i] == 4)
                        b[i] = 1;
                    if (a[i] == ta[i])
                    {
                        a[i]++, b[i]++;
                        if (a[i] == 4)
                            a[i] = 1;
                        if (b[i] == 4)
                            b[i] = 1;
                    }
                    break;
                }
        assert(cnta == n && cntb == n);
        int sum = 0;
        for (int i = 1; i <= 2 * n; i++)
            sum += cmp(a[i], b[i]);
        cout << sum << endl;
        for (int i = 1; i <= 2 * n; i++)
            cout << a[i] << " ";
        cout << endl;
        for (int i = 1; i <= 2 * n; i++)
            cout << b[i] << " ";
        cout << endl;
    }
}

T4 Magical Expression

Given a legal containing | &? 01 suffix expression (given in the form of string, which is "legal", which means that it will become a legal suffix expression after all operators are replaced with operators), try to find out how many substrings satisfy:

  • Will all? Replace with | or & and the string is a legal suffix expression;
  • Is there a way to put all? The method of replacing with | or & makes the result of this formula 0, and there is also an alternative method to make the result 1.

Please output the number of such substrings. Two substrings are different only if they have different lengths or positions.

It's a question that needs to be checked in more than T3, but there are many details, and it can't be adjusted in the end

summary

This game has a large number of yards and is not difficult. However, due to the poor code force, only three questions were cut out, and luogu only ranked rk204. The main problems are:

  • T1 didn't notice that the data range was determined violence, and thought about unnecessary optimization for a long time
  • T2 has no AC
  • T3's first thought was to change winning into drawing
  • T4 this kind of expression inscription is not skilled

Posted on Mon, 08 Nov 2021 03:41:48 -0500 by paha77