Skip to content
Okami's Blog
Go back

Educational Codeforces Round 94 题解

A. String Similarity

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

typedef long long ll;
typedef unsigned long long ull;
const int INF = 0x3f3f3f3f;
const int MOD = 1e9 + 7;

int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);
    int t, n;
    string s;
    cin >> t;
    while(t--){
        cin >> n;
        cin >> s;
        string ans = s.substr(0, n);
        for(int i = 1; i < n; ++i)
            ans[i] = s[i<<1];
        cout<<ans<<endl;
    }
    return 0;
}

B. RPG Protagonist

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

typedef long long ll;
typedef unsigned long long ull;
const int INF = 0x3f3f3f3f;
const int MOD = 1e9 + 7;

int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);
    int t;
    cin >> t;
    while (t--) {
        int p, f, cnt_s, cnt_w, s, w;
        cin >> p >> f >> cnt_s >> cnt_w >> s >> w;

        // Guarantee that s <= w
        if (s > w) {
            swap(s, w);
            swap(cnt_s, cnt_w);
        }

        // Guarantee that p <= f
        if (p > f)
            swap(p, f);

        int ans = 0, p_s, p_w, f_s, f_w;
        for (int i = 0; i <= cnt_s; ++i) {
            if (i * s > p)
                break;
            p_s = i;
            p_w = min(cnt_w, (p - p_s * s) / w);
            f_s = min(cnt_s - p_s, f / s);
            f_w = min(cnt_w - p_w, (f - f_s * s) / w);
            ans = max(ans, p_s + p_w + f_s + f_w);
        }
        cout << ans << endl;
    }
    return 0;
}

C. Binary String Reconstruction

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

typedef long long ll;
typedef unsigned long long ull;
const int INF = 0x3f3f3f3f;
const int MOD = 1e9 + 7;

int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);
    int t;
    cin >> t;
    while (t--) {
        string s;
        int x;
        cin >> s >> x;
        string ans = "";
        for (int i = 0; i < s.length(); i++)
            ans.push_back('?');
        for (int i = 0; i < s.length(); i++)
            if (s[i] == '0') {
                if (i - x >= 0)
                    ans[i - x] = '0';
                if (i + x < s.length())
                    ans[i + x] = '0';
            }

        bool possible = true;
        for (int i = 0; i < s.length(); i++) {
            if (s[i] == '1') {
                bool ok = false;
                if (i - x >= 0) {
                    if (ans[i - x] == '1')
                        ok = true;
                    if (ans[i - x] == '?') {
                        ans[i - x] = '1';
                        ok = true;
                    }
                }
                if (!ok && i + x < s.length()) {
                    if (ans[i + x] == '1')
                        ok = true;
                    if (ans[i + x] == '?') {
                        ans[i + x] = '1';
                        ok = true;
                    }
                }
                if (!ok) {
                    possible = false;
                    break;
                }
            }
        }
        if(!possible)
            cout<<"-1"<<endl;
        else{
            replace(ans.begin(), ans.end(), '?', '1');
            cout<<ans<<endl;
        }
    }
    return 0;
}

D. Zigzags

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

typedef long long ll;
typedef unsigned long long ull;
const int INF = 0x3f3f3f3f;
const int MOD = 1e9 + 7;

const int MAXN = 3000 + 5;
ll a[MAXN];
vector<ll> buckets[MAXN];
ll bucket_heads[MAXN];
#define lowbit(_a) (_a & -_a)
ll c[MAXN << 2], n;
ll sum(ll x) {
    ll ret = 0;
    while (x) {
        ret += c[x];
        x -= lowbit(x);
    }
    return ret;
}
void add(ll x, ll d) {
    while (x <= n) {
        c[x] += d;
        x += lowbit(x);
    }
}

int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);
    ll t;
    cin >> t;
    while (t--) {
        cin >> n;
        for (ll i = 0; i < n; ++i) {
            cin >> a[i];
            buckets[i].clear();
            bucket_heads[i] = 0;
        }
        memset(c, 0, sizeof(c));
        for (ll i = 0; i < n; ++i) {
            buckets[a[i]].push_back(i);
        }
        ll ans = 0;
        for (ll i = 0; i < n; ++i) {
            ll x = i, y;
            bucket_heads[a[i]]++;
            for (ll j = bucket_heads[a[i]]; j < buckets[a[i]].size(); ++j) {
                y = buckets[a[i]][j];
                if (x + 1 <= y - 1)
                    ans += sum(y - 1) - sum(x);
            }
            for (ll j = bucket_heads[a[i]]; j < buckets[a[i]].size(); ++j)
                add(buckets[a[i]][j], 1);
        }
        cout << ans << endl;
    }
    return 0;
}

E. Clear the Multiset

赛场错解

正解

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

typedef long long ll;
typedef unsigned long long ull;
const int INF = 0x3f3f3f3f;
const int MOD = 1e9 + 7;

const int MAXN = 5000 + 5;

int a[MAXN];

int solve(int l, int r) {
    if (l > r)
        return 0;

    int m = min_element(a + l, a + r + 1) - a;
    int a_m = a[m];
    for (int i = l; i <= r; ++i)
        a[i] -= a_m;

    return min(r - l + 1, solve(l, m - 1) + solve(m + 1, r) + a_m);
}

int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);

    int n;
    cin >> n;
    for (int i = 0; i < n; ++i)
        cin >> a[i];
    cout << solve(0, n - 1) << endl;

    return 0;
}

F. x-prime Substrings

正解

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

typedef long long ll;
typedef unsigned long long ull;
const int INF = 0x3f3f3f3f;
const int MOD = 1e9 + 7;

const int CHARACTER_COUNT = 9;

struct AC_auto_mata {
    struct AC_auto_mata_node {
        int next[CHARACTER_COUNT]; // Transition in Trie
        int pre, pre_ch; // The previous node and the character to current node
        bool is_word;

        // When the next transition fails, go back to fail_link and try again
        int fail_link;

        // Cache of where to go from the current node
        int go[CHARACTER_COUNT];

        AC_auto_mata_node() {
            memset(next, -1, sizeof(next));
            memset(go, -1, sizeof(next));
            fail_link = pre = -1;
            is_word = false;
        }
    };

    vector<AC_auto_mata_node> trie;

    AC_auto_mata() { trie.push_back(AC_auto_mata_node()); }

    void insert(string s) {
        int u = 0;
        for (auto ch : s) {
            int c = ch - '1';
            if (trie[u].next[c] == -1) {
                trie.push_back(AC_auto_mata_node());
                trie[trie.size() - 1].pre = u;
                trie[trie.size() - 1].pre_ch = c;
                trie[u].next[c] = trie.size() - 1;
            }
            u = trie[u].next[c];
        }
        trie[u].is_word = true;
    }

    int get_link(int u) {
        if (trie[u].fail_link == -1) {
            if (u == 0 || trie[u].pre == 0)
                trie[u].fail_link = 0;
            else
                trie[u].fail_link = go(get_link(trie[u].pre), trie[u].pre_ch);
        }
        return trie[u].fail_link;
    }

    int go(int u, int c) {
        if (trie[u].go[c] == -1) {
            if (trie[u].next[c] != -1)
                trie[u].go[c] = trie[u].next[c];
            else
                trie[u].go[c] = (u == 0 ? 0 : go(get_link(u), c));
        }
        return trie[u].go[c];
    }
} ac;

string s, t;
int x;

void brute(int sum) {
    if (sum == x) {
        bool is_x_prime = true;
        for (int l = 0; l < t.length(); ++l) {
            int current_sum = 0;
            for (int r = l; r < t.length(); ++r) {
                current_sum += t[r] - '0';
                if (x % current_sum == 0 && current_sum != x)
                    is_x_prime = false;
            }
        }
        if (is_x_prime)
            ac.insert(t);
        return;
    }
    for (int i = 1; i <= min(x - sum, 9); ++i) {
        t += '0' + i;
        brute(sum + i);
        t.pop_back();
    }
}

int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);

    cin >> s >> x;
    brute(0);

    vector<vector<int>> dp(s.size() + 1, vector<int>(ac.trie.size(), INF));
    dp[0][0] = 0;
    for (int i = 0; i < s.size(); ++i)
        for (int j = 0; j < ac.trie.size(); ++j)
            if (dp[i][j] != INF) {
                // Simply delete the next character
                dp[i + 1][j] = min(dp[i + 1][j], dp[i][j] + 1);

                int next = ac.go(j, s[i] - '1');
                if (!ac.trie[next].is_word)
                    // Keep the next character
                    dp[i + 1][next] = min(dp[i + 1][next], dp[i][j]);
            }

    cout << *min_element(dp[s.length()].begin(), dp[s.length()].end()) << endl;
    return 0;
}

G



Previous Post
游戏制作收藏夹
Next Post
《港中深新手村》项目感想