Educational Codeforces Round 119 (Rated for Div. 2)

A - Equal or Not Equal

General idea of the topic

E means equal to the next value, N means unequal
Ask whether the array expressed by this string is legal

thinking

There are some meanings of merging and searching sets
But there are some special places,

  • If all are E, it goes without saying
  • If you want to split the string into two or more arrays, when the first two arrays are connected, two N will be generated, and only one N indicates that it is illegal
    therefore
    As long as there are more than two N's, the string must be legal. On the contrary, when there is only one, it is not legal

code

#include <iostream>
 
using namespace std;
 
const int N = 50 + 10;
 
int n;
string str;
 
int main() {
    int T;
    cin >> T;
    while (T --) {
        cin >> str;
        int cnt = 0;
        for (auto i : str) if (i == 'N') cnt ++;
        if (cnt == 1) puts("NO");
        else puts("YES");
    }
    return 0;
}

B - Triangles on a Rectangle

General idea of the topic

Give you a rectangle W in width and H in height, and points on four sides. What is the area of the largest triangle that can form two points on the same side
The topic is twice the area

thinking

Area of triangle = bottom * height * 2

  • If it is high, we can directly select the point on the opposite side, so that the point can be selected arbitrarily, and the height must be the width or height of the rectangle
  • At the end, you must choose the farthest point on one side

code

#include <iostream>
#include <algorithm>
 
using namespace std;
typedef long long LL;
 
const int N = 2e5 + 10;
 
LL w, h;
LL a[4][N];
 
int main() {
    int T;
    cin >> T;
    while (T --) {
        cin >> w >> h;
        for (int i = 0; i < 4; i ++) {
            cin >> a[i][0];
            for (int j = 1; j <= a[i][0]; j ++) cin >> a[i][j];
            sort(a[i] + 1, a[i] + a[i][0] + 1);
        }
        cout << max(
                h * max(a[0][a[0][0]] - a[0][1], a[1][a[1][0]] - a[1][1]),
                w * max(a[2][a[2][0]] - a[2][1], a[3][a[3][0]] - a[3][1])
                ) << endl;
    }
 
    return 0;
}

C - BA-String

General idea of the topic

Give you a string. You can fill in no more than k b characters at the position of * and ask what is the smaller string x

thinking

Many * strings are separated by A. after simplification, we find that b characters that do not exceed the length of * string can be filled in around a
When the x is small, b must be filled in the last * string first. When the * string reaches the maximum, one will be filled in the previous * string and re filled here
So we found that it is similar to an addition that is different from each base, and what we are looking for is the x - 1 base

code

(the writing is not very good. If there is a better one to share with me)

#include <iostream>
#include <algorithm>
#include <cstring>
 
using namespace std;
typedef long long LL;
 
const int N = 2e3 + 10;
 
LL n, k, x;
string str;
LL a[N], b[N];
int idx, idx2;
 
void calc(LL n, LL k) {
    for (int i = n; i >= 0; i --) {
        b[i] = k % (a[i] + 1);
        k /= (a[i] + 1);
    }
}
 
int main() {
    int T;
    cin >> T;
    while (T --) {
        cin >> n >> k >> x;
        cin >> str;
        idx = idx2 = 0;
        memset(a, 0, sizeof a);
        memset(b, 0, sizeof b);
 
        for (int i = 0; i < n; i ++) {
            if (str[i] == 'a') {
                if (a[idx]) idx ++;
            }
            else a[idx] += k;
        }
 
        //for (int i = 0; i <= idx; i++) cout << a[i] << ' ';
 
        calc(idx, x - 1);
 
        //for (int i = 0; i <= idx; i ++) cout << b[i] << ' ';
 
        for (int i = 0; i < n; i ++) {
            if (str[i] == 'a') {
                if (i != 0 && str[i - 1] == '*') {
                    for (int i = 0; i < b[idx2]; i ++) cout << 'b';
                    idx2 ++;
                }
                cout << 'a';
            }
        }
        if (idx2 <= idx)
            while (idx2 <= idx) {
                for (int i = 0; i < b[idx2]; i ++) cout << 'b';
                idx2 ++;
            }
        cout << endl;
    }
 
    return 0;
}

D - Exact Change

General idea of the topic

You have coins with face values of 1, 2 and 3, and the store has many goods with different prices. Ask the minimum number of coins you need to bring each time you go out to meet different commodity prices

thinking

First of all, greed must be taking the maximum number of 3 coins
Then we'll discuss it in detail

You can refer to it. Please correct the mistakes

code

#include <iostream>
#include <algorithm>
 
using namespace std;
 
int main() {
    int T;
    cin >> T;
    while (T --) {
        int n;
        cin >> n;
        int a[n];
        int t1 = 0, t2 = 0, t3 = 0;
        for (int i = 0; i < n; i ++) {
            cin >> a[i];
            if (a[i] % 3 == 0) t3 = max(t3, a[i]); 
            if (a[i] % 3 == 1) t1 = 1;
            if (a[i] % 3 == 2) t2 = 1;
        }
        sort(a, a + n);
 
        int ans;
        if (a[n - 1] % 3 == 0) {
            ans = a[n - 1] / 3 + (t1 || t2);
        }
        else if (a[n - 1] % 3 == 2) {
            ans = a[n - 1] / 3 + 1 + t1;
        }
        else {
            ans = a[n - 1] / 3 + 1 + (t2 && (a[0] == 1 || t3 + 1 == a[n - 1]));
        }
        cout << ans << endl;
    }
    return 0;
}

E - Replace the Numbers

General idea of the topic

After many operations, find the last value of the array

  • 1 x means insert X
  • 2 x y means to change all previous x to y

thinking

It is said that there is a relationship between maintaining numerical values and maintaining positional relationships. Here we use maintaining positional relationships
Can you maintain data without the traditional parallel query set?
Save the list of all positions when the value is int in map < int, list >
list can be easily transferred

code

#include <iostream>
#include <algorithm>
#include <map>
#include <list>
#include <cstdio>
#include <unordered_map>
 
using namespace std;
 
const int N = 5e5 + 10;
 
int n, idx;
int a[N];
unordered_map<int, list<int> > q;
 
int main() {
    scanf("%d", &n);
    for (int i = 1; i <= n; i ++ ) {
        int op;
        scanf("%d", &op);
 
        if (op == 1) {
            int x;
            scanf("%d", &x);
            q[x].push_back(idx ++);
        }
        else {
            int x, y;
            scanf("%d%d", &x, &y);
            if (x == y) continue;
 
            auto it = q.find(x);
            if (it != q.end()) {
                q[y].splice(q[y].begin(), q[x]);
                q.erase(it);
            }
        }
 
        
    }
    for (auto &i : q) {
        for (auto &j : i.second)
            a[j] = i.first;
    }
    for (int i = 0; i < idx; i ++) printf("%d ", a[i]);
    return 0;
}

Added by zfred09 on Tue, 04 Jan 2022 17:33:42 +0200