Codeforces Round 962 (Div. 3)

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;
}

E. Decode

Idea

这种 01 串问题也不是第一次见了。一种很常规的处理是将 0 视为 -1,1 视为 +1,那么,我们需要做的就是找出给定字符串中有多少个和值为 0 的子串,以及他们分别对答案产生多大的贡献。

要想解决第一个问题,我们可以做一个前缀和,若 a[r] - a[l-1] ==0 ,那么区间 [l,r] 的和值就是 0。之前做过一个求最长平衡串的题目,差不多也是这个思路。然后我们考虑贡献怎么计算。对于任意合法区间 [l,r] ,它产生的贡献是 (len - r) * (l + 1),结合上面提到的前缀和,不难想到,我们可以固定右端点,考虑左边的点形成的所有合法区间的贡献,实际上就是找前面形成了多少和 a[r] 大小相等的 a[i] ,每一个 a[i] 的贡献就是 i + 2 (为什么是 2 呢,模拟一下就知道了),我们可以用 map 去维护这个贡献值,实现细节见代码。

Code

#include <bits/stdc++.h>
using namespace std;
#define int long long
const long long MOD = 1e9 + 7;

void solve()
{
    string text;
    cin >> text;
    int len = text.length();
    map<int, int> m;
    int sum = 0;
    long long ans = 0;
    for (int i = 0; i < len; i++)
    {
        if (text[i] == '0')
        {
            sum--;
        }
        else
        {
            sum++;
        }
        if (sum == 0)
        {
            ans += len - i;
        }
        ans += ((m[sum] % MOD) * ((len - i) % MOD));
        ans %= MOD;
        m[sum] += i + 2;
    }
    cout << ans << endl;
    return;
}

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

Postscript

Rating 469 ,黑历史 get 。

posted @   carboxylBase  阅读(10)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!
点击右上角即可分享
微信分享提示