Codeforces Round 962 (Div. 3)

carboxylBase發表於2024-08-02

Abstract

第一次打 CF 的比賽~~~~


A. Legs

Idea

簽到題,沒什麼好說的。

Code

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

int main()
{
    int t;
    scanf("%d", &t);
    while (t--)
    {
        int n;
        scanf("%d", &n);
        int cnt = n / 4;
        n %= 4;
        cnt += n / 2;
        printf("%d\n", cnt);
    }
    return 0;
}

B. Scale

Idea

還是簽到題,模擬一遍就行了,也沒什麼好說的。

Code

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

int main()
{
    int t;
    scanf("%d", &t);
    while (t--)
    {
        int n, m;
        scanf("%d%d", &n, &m);
        string text;
        string ans[2000];
        for (int i = 1; i <= n; i++)
        {
            cin >> text;
            if (m == 1)
            {
                ans[i - 1] = text;
                continue;
            }
            if (i % m != 1)
            {
                continue;
            }

            for (int j = 0; j < text.length(); j += m)
            {
                ans[(i - 1) / m] += text[j];
            }
        }

        for (int i = 0; i <= (n - 1) / m; i++)
        {
            cout << ans[i] << endl;
        }
    }
    return 0;
}

C. Sort

Idea

和排序沒什麼關係,實際上就是問你對於區間 [l,r] , a 變換幾個字元後,它的組成就可以和 b 一樣,那麼我們只需要給每一個字母都做字首和,就能知道區間 [l,r] 種 a 和 b 的字元組成情況,然後考慮變換的最小次數就可以了,這個需要模擬得出,具體模擬方法見程式碼。

Code

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

int t;
int a[30][300000];
int b[30][300000];
void solve()
{
    int n, m;
    cin >> n >> m;
    string text;
    cin >> text;

    int len = text.length();
    for (int i = 0; i < len; i++)
    {
        for (int j = 0; j < 26; j++)
        {
            a[j][i + 1] = a[j][i];
        }
        a[text[i] - 'a'][i + 1]++;
    }

    cin >> text;

    for (int i = 0; i < len; i++)
    {
        for (int j = 0; j < 26; j++)
        {
            b[j][i + 1] = b[j][i];
        }
        b[text[i] - 'a'][i + 1]++;
    }

    for (int i = 0; i < m; i++)
    {
        int ans = 0;
        int l, r;
        cin >> l >> r;
        int sum = 0;
        for (int i = 0; i < 26; i++)
        {
            int new_sum = sum + (a[i][r] - a[i][l - 1]) - (b[i][r] - b[i][l - 1]);
            // 如此計算變換的最小次數
            if (new_sum > 0 && sum <= 0)
            {
                ans += new_sum;
            }
            else if (new_sum < 0 && sum >= 0)
            {
                ans -= new_sum;
            }
            else if (sum <= 0 && new_sum < sum)
            {
                ans += sum - new_sum;
            }
            else if (sum >= 0 && new_sum > sum)
            {
                ans += -sum + new_sum;
            }

            sum = new_sum;
        }
        cout << ans << endl;
    }

    return;
}

int main()
{
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    cin >> t;
    while (t--)
    {
        solve();
    }
    return 0;
}

D. Fun

Idea

直接列舉 a,b,c 當然會超時了,實際上,我們可以只列舉 b、c ,然後根據 b、c 的取值判斷 a 的範圍,這裡需要做一些公式推導。為了列舉出的保證情況不重複,我們可以規定 a > b > c,然後再考慮 a、b、c 中有數字相等的情況即可。

Code

#include <bits/stdc++.h>
using namespace std;
#define int long long
signed main()
{
    int t;
    scanf("%lld", &t);
    while (t--)
    {
        int n, x;
        scanf("%lld%lld", &n, &x);
        bool ok = 1;
        int cnt = 0;
        for (int b = 1; 3 * b + 3 <= x; b++)
        {
            for (int c = b + 1; ok; c++)
            {
                int a = x - b - c;
                a = min(a, (n - b * c) / (b + c));
                if (a <= c)
                {
                    break;
                }
                int sum = a - c;
                cnt += 6 * sum;
            }
        }
        int num = pow(n / 3, 0.5);
        cnt += min(x / 3, num);
        for (int b = 1;; b++)
        {
            int a = min((n - b * b) / 2 / b, x - 2 * b);
            if (a <= 0)
            {
                break;
            }
            if (a < b)
            {
                cnt += 3 * (a);
            }
            else
            {
                cnt += 3 * (a - 1);
            }
        }
        cout << cnt << endl;
    }
    return 0;
}

相關文章