Codeforces Round 833 (Div. 2)

比赛链接:Dashboard - Codeforces Round 833 (Div. 2) - Codeforces

B. Diverse Substrings

题意:

思路:

当字符串长度 > 10 时,每个字符出现的次数至少是 2 次 ( 0 ~ 9 个出现一次,剩余字符出现 )

当字符串长度 > 20 时,每个字符出现的次数至少是 3 次

......

当字符串长度 > 100 时,每个字符出现的次数至少是 11 次

但是数字种类就只有 10 个 ( 0 ~ 9 ),所以当字符串长度 > 100时,一定是错误的

所以只用枚举长度在 100 以内的即可

AC代码:

#include<bits/stdc++.h>
using namespace std;
#define int long long
void solve()
{
    int n; cin >> n;
    string s; cin >> s;
    int ans = 0;
    for( int i = 0 ; i < n ; i++)
    {
        int cnt[10] = { 0 };
        int mx = 0; int temp = 0;
        for( int j = i ; j < min( i + 101 , n ) ; j++ )
        {
            if( cnt[ s[j] - '0' ] == 0 ) temp++;
            cnt[ s[j] - '0' ]++;
            mx = max( mx , cnt[s[j] - '0']);
            if( temp >= mx )ans++;
        }
    }
    cout << ans << endl;
}
signed main()
{
    int tt; cin >> tt;
    while(tt--)solve();
    return 0;
}

C. Zero-Sum Prefixes

题意:

 

思路:(贪心)

n = 9

a =              1         0       0        1       -1         0      1       0        -1

前缀和         1         1       1        2        1         1      2        2        1

                               x        y                             z               p

   要使前缀尽量变为0 ,所以这个数就要尽量变成 [ y , z )中前缀和的众数的相反数,此时贡献最大

AC代码:

#include<bits/stdc++.h>
using namespace std;
#define int long long
void solve()
{
    int n; cin >> n;
    vector<int> a(n + 1);
    for( int i = 1; i <= n; i++ ) cin >> a[i];
    vector<int> pre(n + 1);
    vector<int> b;
    for( int i = 1; i <= n; i++)
    {
        pre[i] = pre[i-1] + a[i];
        if( !a[i] ) b.push_back(i);
    }
    if( b.size() == 0 ) // 没有0的时候单独讨论一下
    {
        int ans = 0;
        for( int i = 1 ; i <= n; i++) 
        {
            if( pre[i] == 0 ) ans++;
        }
        cout << ans << endl;
        return;
    }
    int ans = 0;
    for( int i = 1 ; i < b[0] ; i++)
        if( !pre[i] )ans++; // 在第一个0之前的前缀和有多少贡献

    b.push_back( n + 1 ); // 为了下面与 b[ i + 1 ]那个方便
    for( int i = 0 ; i < b.size() - 1 ; i++)
    {
        map<int,int> mp;
        int mx = 0;
        for( int j = b[i] ; j < b[i + 1] ; j++)
        {
            mp[pre[j]]++;
            mx = max( mx , mp[pre[j]] ); // 找众数
        }
        ans += mx;
    }
    cout << ans << endl;
}
signed main()
{
    int tt; cin >> tt;
    while(tt--)solve();
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值