Educational Codeforces Round 125 (Rated for Div. 2)

Contest Info


Practice Link

Solved A B C D E F
4 / 6 O O O Ø - -
  • O 在比赛中通过
  • Ø 赛后通过
  • ! 尝试了但是失败了
  • - 没有尝试

Reply


读题假了一万年,感觉要加训了😭

不懂E、F,2-sat就不写了(摆烂),计数等题解补

Solutions


A. Integer Moves

题意:
\((0, 0)\) 点走到 \((x, y)\) 点,若两点欧几里得距离为整数就能直接走,问最多走几步。

思路:
值域很小,暴力判断下就行。

B. XY Sequence

思路:
按照题意模拟即可。贪心地加 \(x\) ,不能加就减 \(y\)

C. Bracket Sequence Deletion

题意:
给定括号序列,每次删除一个最短的好前缀。问操作数和剩余序列长度。

当一个括号序列正则或者回文即视为好。

思路:
读题读晕了。

分开考虑左右括号,发现左括号在长度为 \(2\) 时一定回文或正则,直接删去。右括号一定不会正则,那么找到下一个右括号所在的位置,中间都是左括号,一定回文。

#include <bits/stdc++.h>

using namespace std;

inline int rd() {
    int f = 0; int x = 0; char ch = getchar();
    for (; !isdigit(ch); ch = getchar()) f |= (ch == '-');
    for (; isdigit(ch); ch = getchar()) x = (x << 1) + (x << 3) + ch - '0';
    if (f) x = -x;
    return x;
}

typedef long long ll;

const int inf = 0x3f3f3f3f;
const ll INF = 0x3f3f3f3f3f3f3f3f;
char s[500005];
void solve() {
    int pos = -1;
    int n = rd();
    vector<int> nxt(n + 1);
    scanf("%s", s);
    for (int i = n - 1; i >= 0; --i) {
        nxt[i] = pos;
        if (s[i] == ')') pos = i;
    }
    int len = n, op = 0;
    for (int i = 0; i < n; ++i) {
        if (s[i] == '(' && i < n - 1) {
            i++;
            op++;
            len -= 2;
            continue;
        }
        if (nxt[i] == -1) break;
        op++;
        len -= nxt[i] - i + 1;
        i = nxt[i];
    }
    printf("%d %d\n", op, len);
}

int main() {
    int t = 1;
    t = rd();
    while (t--) solve();
    return 0;
}

D. For Gamers. By Gamers.

题意:
现有 \(n\) 种单位和 \(C\) 元,每种单位拥有花费、攻击力和生命值。你要独立地去打 \(m\) 种怪,你每次可以选择 其中一种单位,召唤多次,一起与怪兽战斗,问让己方单位都存活下来时地最小花费。

注意伤害是持续性的,也就是攻击力是一秒钟造成的总伤害。

思路:
不知道为什么读不懂题意。

理解了之后发现就是求满足所有单位中 \(x \cdot d_i \cdot h_i > D \cdot H\) 并且 \(x \cdot c_i \leq C\)\(x \cdot c_i\) 的最小值。我们观察到数字都很大,但是 \(C\) 比较小,提示我们求出花费 \(c\) 元能取得的最大 \(d_i \cdot h_i\),那么之后就可以二分来确定答案了。

因为只能多次选择其中一种单位,每个单位能影响到的值其实就是能被 \(c_i\) 整除的数,那么筛选一遍因子就能 \(O(nlog_n)\) 跑完了。

注意最后要取一下前缀最大值,将数组的意义转换成至多花费 \(c\) 元能取得的最大值。因为原先只受因子影响,不一定会单调递增。

然后注意 \(H\) 输入的时候会爆 \(int\)

#include <bits/stdc++.h>

using namespace std;

typedef long long ll;

ll rd() {
    ll t;
    cin >> t;
    return t;
}

const int inf = 0x3f3f3f3f;
const ll INF = 0x3f3f3f3f3f3f3f3f;

void solve() {
    int n = rd(), v = rd();
    vector<ll> w(v + 1);
    for (int i = 1; i <= n; ++i) {
        ll c = rd(), d = rd(), h = rd();
        ll val = 1ll * d * h;
        w[c] = max(w[c], val);
    }
   
    for (int i = 1; i <= v; ++i) {
        for (int j = i + i; j <= v; j += i) {
            w[j] = max(w[j], w[i] * (j / i));
        }
    }

    for (int i = 2; i <= v; ++i) {
        w[i] = max(w[i], w[i - 1]);
    }
    int m = rd();
    for (int i = 1; i <= m; ++i) {
        ll d = rd(), h = rd();
        ll val = 1ll * d * h;
        int pos = upper_bound(w.begin(), w.end(), val) - w.begin();

        if (pos > v) {
            cout << "-1 ";
        } else {
            cout << pos << " ";
        }
    }
}

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);cout.tie(nullptr);
    cout << fixed << setprecision(20);
    int t = 1;
    while (t--) solve();
    return 0;
}
posted @ 2022-03-23 10:36  stff577  阅读(140)  评论(0编辑  收藏  举报