CF 1389 题解

A. LCM Problem

观察可得,第一个数的两倍小于等于第二个数时,有解,且这组解必定能被构造。

AC代码:

#include <bits/stdc++.h>

using namespace std;


signed main()
{
    cin.tie(nullptr);
    ios_base::sync_with_stdio(false);
    int t;
    cin >> t;
    while(t --)
    {
        int l, r;
        cin >> l >> r;
        if(2 * l <= r)
        {
            cout << l << ' ' << 2 * l << '\n';
        }
        else
        {
            cout << "-1 -1" << '\n';
        }
    }
}


B. Array Walk

无法暴力枚举,考虑 D P DP DP,第一思路是维护当前位置,总步数,向左走的步数。
F [ i ] [ j ] [ k ] F[i][j][k] F[i][j][k], i i i 是当前位置, j j j 是总步数, k k k 是向左走的步数。
两个 1 e 5 1e5 1e5 的数据范围,考虑优化 D P DP DP方程。
我们可以用推出向左走的步数和当前位置推出总步数,那么 D P DP DP方程优化到了二维,可以通过。时间复杂度为 Θ ( n ) \Theta(n) Θ(n)。

AC代码:

#include <bits/stdc++.h>

using namespace std;


signed main()
{
    cin.tie(nullptr);
    ios_base::sync_with_stdio(false);
    int t;
    cin >> t;
    while(t --)
    {
        int n, k, z;
        cin >> n >> k >> z;
        vector <int> a(n + 5);
        for(int i = 1; i <= n; ++i)
        {
            cin >> a[i];
        }
        vector <vector <int>> f(n + 5, vector <int> (z + 5, 0));
        int ans = 0;
        f[1][0] = a[1];
        for(int i = 0; i <= z; ++i)
        {
            for(int j = 1; j <= n; ++j)
            {
                f[j][i] = max(f[j - 1][i], (i && j != n ? f[j + 1][i - 1] : 0)) + a[j];
                if(j + (i << 1) - 1 == k)
                {
                    ans = max(ans, f[j][i]);
                }
            }
        }
        cout << ans << '\n';
    }
}


C. Good String

观察可得只有 A A A A A A AAAAAA AAAAAA 和 A B A B A B ABABAB ABABAB 串能满足题意。
两层 f o r for for循环暴力枚举 0 − 9 0 -9 0−9,另一种情况特判下最多字符,然后两者取 m i n min min 即可。

AC代码:

#include <bits/stdc++.h>

using namespace std;


signed main()
{
    cin.tie(nullptr);
    ios_base::sync_with_stdio(false);
    int t;
    cin >> t;
    while(t --)
    {
        string s;
        cin >> s;
        int ans = 1e9;
        unordered_map <int, int> mp;
        int len = s.size();
        for(auto x : s)
        {
            ans = min(ans, len - (++mp[x - '0']));
        }
        for(int i = 0; i <= 9; ++i)
        {
            for(int j = 0; j <= 9; ++j)
            {
                if(i == j)
                    continue;
                int mark = 0;
                int res = 0;
                for(auto x : s)
                {
                    if((!mark && x - '0' == i) || (mark && x - '0' == j))
                    {
                        res ++;
                        mark ^= 1;
                    }
                }
                if(res & 1) res --;
                ans = min(ans, len - res);
            }
        }
        cout << ans << '\n';
    }
}

D. Segment Intersections

恶心的分类讨论, w a wa wa傻了。

两种大类,相交或不相交。
不相交极其恶心,要考虑 1 1 1 代价和 2 2 2 代价之间的大小关系,继续细分即可。

AC代码:

#include <bits/stdc++.h>

using namespace std;


signed main()
{
    cin.tie(nullptr);
    ios_base::sync_with_stdio(false);
    int t;
    cin >> t;
    while(t --)
    {
        long long n, k, l1, r1, l2, r2;
        cin >> n >> k >> l1 >> r1 >> l2 >> r2;
        long long L = max(l1, l2);
        long long R = min(r1, r2);
        if(L <= R)
        {
            long long mix_val = (R - L) * n;
            if(mix_val >= k)
            {
                cout << 0 << '\n';
            }
            else
            {
                k -= mix_val;
                long long L1 = min(l1, l2);
                long long R1 = max(r1, r2);
                long long cha_seg = (R1 - L1) - (R - L);
                long long max_val = cha_seg * n;
                if(max_val >= k)
                {
                    cout << k << '\n';
                }
                else
                {
                    cout << max_val + (k - max_val) * 2 << '\n';
                }
            }
        }
        else
        {
            long long ans = 0;
            long long len = max(r1, r2) - min(l1, l2);
            long long cost1 = L - R + len;
            long long cost2 = len * 2;
            if(cost1 >= cost2)
            {
                if(k <= len)
                {
                    ans = cost1 - (len - k);
                }
                else
                {
                    ans += cost1;
                    k -= len;
                    ans += k * 2;
                }
            }
            else
            {
                long long quo = k / len;
                long long rem = k % len;
                int min_val = min(quo, n);
                ans += min_val * cost1;
                quo -= min_val;
                long long lst = n;
                n -= min_val;
                if(quo || !n)
                {
                    ans += (quo * len + rem) * 2;
                }
                else
                {
                    if(n != lst)
                        ans += min(cost1 - (len - rem), rem * 2);
                    else
                        ans += cost1 - (len - rem);
                }
            }
            cout << ans << '\n';
        }
    }
}


上一篇:cf 1550E. Stringforces (二分+状压)


下一篇:世末之旅