2021牛客暑期多校训练营4

C. LCS

#include <iostream>
#include <cstring>
#include <algorithm>
#include <string>
using namespace std;

const int N = 1005;

int f[N][N];

int lcs(string &a, string &b, int n) {
    for (int i = 1; i <= n; i++) {
        for (int j = 1; j <= n; j++) {
            f[i][j] = max(f[i][j - 1], f[i - 1][j]);
            if (a[i - 1] == b[j - 1]) {
                f[i][j] = max(f[i][j], f[i - 1][j - 1] + 1);
            }
        }
    }
    return f[n][n];
}

void push(string &s, char ch, int time) {
    for (int i = 0; i < time; i++) {
        s.push_back(ch);
    }
}

void solve() {
    int a, b, c, n;
    scanf("%d %d %d %d", &a, &b, &c, &n);
    int arr[3] = {a, b, c};
    sort(arr, arr + 3, std::greater<int>());
    int x = arr[0], y = arr[1], z = arr[2];
    if (x + y - z > n) {
        puts("NO");
        return;
    }
    string s1, s2, s3;
    push(s1, 'a', x);
    push(s1, 'x', n - s1.size());
    push(s2, 'a', x);
    push(s2, 'b', y - z);
    push(s2, 'y', n - s2.size());
    push(s3, 'a', z);
    push(s3, 'b', y - z);
    push(s3, 'z', n - s3.size());
    string *ss[] = {&s1, &s2, &s3};
    int per[] = {0, 1, 2};
    do {
        string &ss1 = *ss[per[0]], &ss2 = *ss[per[1]], &ss3 = *ss[per[2]];
        if (lcs(ss1, ss2, n) == a && lcs(ss2, ss3, n) == b && lcs(ss1, ss3, n) == c) {
            printf("%s\n%s\n%s\n", ss1.c_str(), ss2.c_str(), ss3.c_str());
        }
    } while (next_permutation(per, per + 3));
}

int main() {
    solve();
    return 0;
}

F. Just a joke

#include <iostream>
#include <cstring>
#include <cstdio>
using namespace std;

const int N = 1003;

int father[N], vis[N];

int Find(int x) {
    return father[x] == x ? x : father[x] = Find(father[x]);
}

void Union(int u, int v) {
    u = Find(u), v = Find(v);
    if (u != v) father[u] = v;
}

void solve() {
    for (int i = 0; i < N; i++) {
        father[i] = i;
    }
    int n, m;
    scanf("%d %d", &n, &m);
    int cnt = 0;
    for (int i = 0; i < m; i++) {
        int u, v;
        scanf("%d %d", &u, &v);
        if (Find(u) != Find(v)) Union(u, v);
        else cnt++;
    }
    for (int i = 1; i <= n; i++) {
        int t = Find(i);
        if (!vis[t]) {
            vis[t] = true;
            cnt++;
        }
    }
    if (cnt & 1) puts("Alice");
    else puts("Bob");
}

int main() {
    solve();
    return 0;
}

I. Inverse Pair

#include <iostream>
#include <cstring>
#include <cstdio>
using namespace std;

const int N = 200005;

int a[N], vis[N], tmp[N];
long long ans = 0;

void mergeSort(int *a, int l, int r) {
    if (l == r) return;
    int mid = l + r >> 1;
    mergeSort(a, l, mid);
    mergeSort(a, mid + 1, r);
    int i = l, j = mid + 1;
    int tot = 0;
    while (i <= mid && j <= r) {
        if (a[j] < a[i]) {
            tmp[tot++] = a[j++];
            ans = ans + mid - i + 1;
        } else {
            tmp[tot++] = a[i++];
        }
    }
    while (i <= mid) tmp[tot++] = a[i++];
    while (j <= r) tmp[tot++] = a[j++];
    for (i = 0, j = l; i < tot; i++, j++) {
        a[j] = tmp[i];
    }
}

void solve() {
    int n;
    scanf("%d", &n);
    for (int i = 0; i < n; i++) {
        scanf("%d", &a[i]);
    }
    for (int i = 0; i < n; i++) {
        if (!vis[a[i] + 1]) {
            vis[a[i]] = true;
        } else {
            vis[++a[i]] = true;
        }
    }
    mergeSort(a, 0, n - 1);
    cout << ans << endl;
}

int main() {
    solve();
    return 0;
}

J. Average

#include <iostream>
#include <cstring>
#include <cstdio>
using namespace std;

const int N = 100005;

int a[N];
double pre[N];

bool check(int n, int x, double ave) {
    for (int i = 1; i <= n; i++) {
        pre[i] = pre[i - 1] + a[i] - ave;
    }
    double minn = 0;
    for (int i = x; i <= n; i++) {
        minn = min(minn, pre[i - x]);
        if (pre[i] - minn >= 0) return true;
    }
    return false;
}

double work(int n, int x) {
    double l = 1e6, r = -1e6;
    for (int i = 1; i <= n; i++) {
        scanf("%d", &a[i]);
        l = min(l, (double)a[i]);
        r = max(r, (double)a[i]);
    }
    while (r - l > 1e-8) {
        double mid = (l + r) / 2;
        if (check(n, x, mid)) l = mid;
        else r = mid;
    }
    return l;
}

void solve() {
    int n, m, x, y;
    scanf("%d %d %d %d", &n, &m, &x, &y);
    double aa = work(n, x);
    double bb = work(m, y);
    printf("%.8lf\n", aa + bb);
}

int main() {
    solve();
    return 0;
}
posted @ 2021-10-01 18:37  牟翔宇  阅读(19)  评论(0编辑  收藏  举报