Codeforces Round 905 (Div. 3)

发布时间 2023-10-24 01:05:26作者: value0

Codeforces Round 905 (Div. 3)

A. Morning

解题思路:

首先\(4\)个数字都要打印出来,所以\(ans\)起始值为\(4\)

接着就是从左向右移动绝不回头,鼠标移动的距离和就是两两数字之差。

注意:这里\(0\)位置其实是\(10\).

代码:

#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using pii = pair<int, int>;
using pll = pair<ll, ll>;
#define fi first
#define se second
void solve()
{
    string s;
    cin >> s;
    char cur = '1';
    int ans = 4;
    for (int i = 0; i < 4; i++)
    {
        if (s[i] == '0')
        {
            s[i] = '9' + 1;
        }
        ans += abs(s[i] - cur);
        cur = s[i];
    }
    cout << ans << endl;
}

int main()
{
    std::ios::sync_with_stdio(0);
    std::cin.tie(0);
    std::cout.tie(0);
    int t = 1;
    cin >> t;
    while (t--)
    {
        solve();
    }
    return 0;
}

B. Chemistry

解题思路:

回文串中最多有一种字母出现奇数次。

所以,我们的最小合法操作步数就是让出现奇数次的字母最多为\(1\)种。

如果初始情况出现奇数次的字母大于一个(有\(m\)个),那么我们就要判断是否\(k \geq m - 1\)

如果奇数次的字母有一个,那么若\(k\)为偶数,我们一定有方案使减完\(k\)个字母后,奇数次字母只有一个;若\(k\)为奇数,那么我们一定有方案使减完\(k\)个字母后,全部都是出现偶数次的字母,也合法。

代码:

#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using pii = pair<int, int>;
using pll = pair<ll, ll>;
#define fi first
#define se second
void solve()
{
    int n, k;
    cin >> n >> k;
    string s;
    cin >> s;
    vector<int> cnt(30);
    for (auto c : s)
    {
        cnt[c - 'a']++;
    }
    int ji = 0;
    int ou = 0;
    for (int i = 0; i < 26; i++)
    {
        if (cnt[i])
        {
            if (cnt[i] & 1)
            {
                ji++;
            }
            else
            {
                ou++;
            }
        }
    }
    int res = max(0, ji - 1);
    k -= res;
    if (k >= 0)
    {
        puts("YES");
    }
    else
    {
        puts("NO");
    }
}

int main()
{
    std::ios::sync_with_stdio(0);
    std::cin.tie(0);
    std::cout.tie(0);
    int t = 1;
    cin >> t;
    while (t--)
    {
        solve();
    }
    return 0;
}

C. Raspberries

解题思路:

本题\(k\)很小,可直接暴力计算到达出现第一个\(k\)的倍数的最短距离。

\(k = 4\)的时候,有因子\(2\)。因此还要讨论到达序列得到有两个\(2\)的倍数的最短距离。

代码:

#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using pii = pair<int, int>;
using pll = pair<ll, ll>;
#define fi first
#define se second
void solve()
{
    int n, k;
    cin >> n >> k;
    vector<int> a(n + 1);
    bool f = false;
    int ans = 1e9;
    for (int i = 1; i <= n; i++)
    {
        cin >> a[i];
        if (a[i] % k == 0)
        {
            f = true;
        }
        int t = a[i];
        int cnt = 0;
        while (t % k)
        {
            t++;
            cnt++;
        }
        ans = min(ans, cnt);
    }
    if (k == 4)
    {
        int fb = 1e9;
        int sb = 1e9;
        for (int i = 1; i <= n; i++)
        {
            int cnt = 0;
            int t = a[i];
            while (t % 2)
            {
                t++;
                cnt++;
            }
            if (fb >= cnt)
            {
                sb = fb;
                fb = cnt;
            }
            else if (sb > cnt)
            {
                sb = cnt;
            }
        }
        ans = min(ans, sb + fb);
    }
    if (f)
    {
        cout << 0 << endl;
    }
    else
    {
        cout << ans << endl;
    }
    // cout << n << ' ' << k << endl;
}

int main()
{
    std::ios::sync_with_stdio(0);
    std::cin.tie(0);
    std::cout.tie(0);
    int t = 1;
    cin >> t;
    while (t--)
    {
        solve();
    }
    return 0;
}

D. In Love

解题思路:

若当前集合中至少有两个线段,如果当前最小的右端点小于当前最大左端点,答案就是\(yes\)

注意:不能按\(pair<int,int>\)来排序。

举例:\((1,5),(5,6),(2,4)\)

代码:

#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using pii = pair<int, int>;
using pll = pair<ll, ll>;
#define fi first
#define se second
void solve()
{
    int n;
    cin >> n;
    multiset<int> a, b;
    int m = n;
    int cnt = 0;
    while (m--)
    {
        string s;
        cin >> s;
        int l, r;
        cin >> l >> r;
        if (s == "+")
        {
            a.insert(l);
            b.insert(r);
        }
        else
        {
            a.erase(a.lower_bound(l));
            b.erase(b.lower_bound(r));
        }
        if ((a.size() > 1 && (*a.rbegin() > *b.begin())))
        {
            cout << "YES\n";
        }
        else
        {
            cout << "NO\n";
        }
    }
}

int main()
{
    std::ios::sync_with_stdio(0);
    std::cin.tie(0);
    std::cout.tie(0);
    int t = 1;
    // cin >> t;
    while (t--)
    {
        solve();
    }
    return 0;
}

E. Look Back

解题思路:

设存在\(a,b\).其中\(a \leq b <2a\)。那么\(b*2^{k-1}<a * 2^k < b*2^k\)

所以,预处理得到初始相邻元素之间的操作次数差。接下来从左向右递推,记录当前值要大于等于右值需要加上的操作次数即可。

代码:

#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using pii = pair<int, int>;
using pll = pair<ll, ll>;
#define fi first
#define se second

ll qmi(ll a, ll b)
{
    ll res = 1;
    while (b)
    {
        if (b & 1)
        {
            res = res * a;
        }
        a = a * a;
        b >>= 1;
    }
    return res;
}
ll lowbit(ll x)
{
    return x & -x;
}

void solve()
{
    int n;
    cin >> n;
    vector<ll> a(n + 1), f(n + 1);
    ll ans = 0;
    for (int i = 1; i <= n; i++)
    {
        cin >> a[i];
        if (i > 1)
        {
            if (a[i] < a[i - 1])
            {
                ll x = a[i - 1];
                ll y = a[i];
                int cnt = 0;
                while (y < x)
                {
                    y <<= 1;
                    cnt++;
                }
                f[i] = cnt;
            }
        }
    }
    for (int i = 2; i <= n; i++)
    {
        if (f[i])
        {
            f[i] += f[i - 1];
        }
        else
        {
            ll x = a[i];
            ll y = a[i - 1];
            ll cnt = 0;
            while (y < x)
            {
                cnt++;
                y <<= 1;
            }
            if (y > x)
            {
                cnt--;
            }
            f[i] = max(0ll, f[i - 1] - cnt);
        }
        // cout << i << ' ' << f[i] << endl;
        ans += f[i];
    }
    cout << ans << endl;
}

int main()
{
    std::ios::sync_with_stdio(0);
    std::cin.tie(0);
    std::cout.tie(0);
    int t = 1;
    cin >> t;
    while (t--)
    {
        solve();
    }
    return 0;
}