跳转至

2025“钉耙编程”中国大学生算法设计春季联赛(4)

2025-03-28 打得还行的一集,赛时写了四题,但是全是很简单的题啊。下一题我就刚才看题解都看得很难受。看大佬代码强行理解一下

今天是周一,03-31,不仅刚补这篇题解,还有VP的区域赛的也等着我。先把这篇整了,回去学个算法,然后VP一场EDU。

感觉像这种还是干脆就在Vscode写可能还比较舒服,不然有点麻烦,就得用两个软件,切文件还不方便,而且Vscode还更流畅一些。

1001

比较简单的模拟题,但是我把题目看错了。。。弘文了。题目说的是第二次及以后收到的伤害是 \(\frac{u}{2}\) ,但是我以为每次受到的伤害是上一次受到的伤害除以2。。。后来重新看了一下发现了。

void ChatGptDeepSeek()
{
    long long n, u, k, hq;
    cin >> n >> u >> k >> hq;
    vector<int> cnt(n + 1);
    priority_queue<array<int, 3>, vector<array<int, 3>>, greater<>> pq;
    vector<int> time(n + 1), lst(n + 1, 2 * u);
    multiset<int> st;
    for (int i = 1; i <= n; i++)
    {
        int a, h;
        cin >> a >> h; // 攻击 血量
        //  血量 攻击 下标
        pq.push({h, a, i});
        st.insert(a);
    }
    int ans = 0;
    while (!pq.empty())
    {
        auto [h, a, i] = pq.top();
        // assert(h >= 0 && time[i] <= k);
        pq.pop();
        // assert(i <= n);

        if (time[i] == 0)
        {
            h -= u;
            lst[i] = u;
        }
        else
        {

            h -= u / 2;
        }
        if (h <= 0)
        {
            ans++;
            st.erase(st.lower_bound(a));
        }
        if (st.empty())
            break;
        int hurt = *st.rbegin();

        time[i]++;

        hq -= hurt;
        if (hq <= 0)
        {
            break;
        }
        if (time[i] < k && h > 0)
        {
            pq.push({h, a, i});
        }
    }
    cout << n - st.size() << '\n';
}

1003

刚补(抄)的,感觉能看懂一点的。。大概强行理解吧。

我只能说还是不太懂,已经看了很久了。或许以后再回来看看吧。

void ChatGptDeepSeek()
{
    ll k, b, c, v;
    cin >> k >> b >> c >> v;
    ll led = 0;
    // p^c <=v
    ll ans = 0;
    for (int i = 60; i >= 0; i--)
    {
        if (v >> i & 1)
        {
            ll u = (led ^ c) & ((1LL << 61) - (1LL << i));
            ll L = u - 1, R = u + (1LL << i) - 1;
            // [u,R] 是 i全为0的区间,在这之后 i 这个地方全会为1了
            // 那么我们后面其实会漏掉 p=v 的情况
            if (R >= b)
                ans += (R - b) / k + 1;
            if (L >= b)
                ans -= (L - b) / k + 1;
            led |= 1LL << i;
        }
    }
    if ((v ^ c) >= b && ((v ^ c) - b) % k == 0)
        ans++;
    cout << ans << '\n';
}

1005

水题。。

void ChatGptDeepSeek()
{
    int P, n, k;
    cin >> P >> n >> k;
    vector<double> p1(1, 1);
    vector<int> p2(1, 0);
    // priority_queue<int, vector<int>, greater<>> p1;
    // priority_queue<int> p2;
    for (int i = 1; i <= n; i++)
    {
        int t, p;
        cin >> t >> p;
        if (!t)
            p1.push_back(p / 10.0);
        else
            p2.push_back(p);
    }
    sort(p1.begin() + 1, p1.end());
    sort(p2.begin() + 1, p2.end(), greater<>());
    for (int i = 1; i < p1.size(); i++)
        p1[i] = p1[i - 1] * p1[i];
    //  cerr << p1[i] << " \n"[i + 1 == p1.size()];
    for (int i = 1; i < p2.size(); i++)
        p2[i] = p2[i - 1] + p2[i];
    //  cerr << p2[i] << " \n"[i + 1 == p2.size()];

    double ans = P;

    int s1 = p1.size() - 1, s2 = p2.size() - 1;
    for (int i = max(0, k - s2); i <= min(k, s1); i++)
    {
        if (k - i > s2)
            ans = min(ans, P * p1[i]);
        else
            ans = min(ans, P * p1[i] - p2[k - i]);
        // cerr << "P*p1 :" << P * p1[i] << " p2[k-i]: " << p2[k - i] << '\n';
        // cerr << i << " " << k - i << " " << ans << '\n';
    }
    ans = max(ans, 0.0);
    cout << ans << '\n';
}

1006

树状数组模板题。

struct Fenwick
{
    vector<ll> b;
    Fenwick(int n)
    {
        b = vector<ll>(n + 1);
    }
    int lowbit(int x) { return (x) & (-x); }
    void add(int i, int x)
    {
        while (i && i < b.size())
        {
            b[i] += x;
            i += lowbit(i);
        }
    }
    ll query(int i)
    {
        ll res = 0;
        while (i)
        {
            res += b[i];
            i -= lowbit(i);
        }
        return res;
    }
};
void ChatGptDeepSeek()
{
    int n, q;
    cin >> n >> q;
    vector<int> a(n + 1);
    Fenwick C(n + 1);
    for (int i = 1; i <= n; i++)
    {
        cin >> a[i];
        C.add(i, a[i]);
    }
    int tot = 1;
    ll ans = 0;
    while (q--)
    {
        int op, x, y;
        cin >> op >> x >> y;
        if (op == 1)
        {
            C.add(x, y - a[x]);
            a[x] = y;
        }
        else
        {
            ll res = C.query(y) / 100 - C.query(x - 1) / 100;
            ans = ans ^ (res * tot);
            tot++;
        }
    }
    cout << ans << '\n';
}

1008

基础的一个DP,但是感觉我写得不够流畅,还是写了一会才写出来的。

void ChatGptDeepSeek()
{
    int n, k;
    cin >> n >> k;
    vector<vector<int>> dp(n + 1, vector<int>(k + 1)), a(n + 1, vector<int>(k + 1));
    /* 到i 分了j段 */
    for (int i = 1; i <= n; i++)
        for (int j = 1; j <= k; j++)
            cin >> a[i][j];
    for (int i = 1; i <= n; i++)
    {
        for (int j = 1; j <= k; j++)
        {
            dp[i][j] = max(dp[i][j], dp[i - 1][j] + a[i][j]);
            dp[i][j] = max(dp[i][j], dp[i][j - 1]);
            // cerr << dp[i][j] << " \n"[j == k];
        }
    }
    cout << dp[n][k] << '\n';
}