2022 Jiangsu Collegiate Programming Contest - L. Collecting Diamonds

L. Collecting Diamonds

题目描述

time limit per test1 second
memory limit per test256 megabytes
inputstandard input
outputstandard output

Our best explorer, Vingying, finds a deep cave that is full of diamonds! Well, he is a very careful man, so he decides to do some research before collecting them.

The diamonds can be divided into three kinds, noted as A,B,C for convenience. There are a total of n diamonds in a row, which can be regarded as a sequence s1,s2,…,sn from left to right. Vingying will perform the operation several times, which consists of the following three steps in order.

1.Choose an index i (1≤i≤n−2) satisfying si=A, si+1=B, si+2=C.
2.If the index is odd, then collect si and si+2; otherwise, collect si+1.
3.Update n to the number of diamonds left and reindex the diamonds.
For example, s=ABCABC. We can choose index 1 and collect 1,3, then s becomes BABC indexed 1,2,3,4. But if we choose index 4 and collect 5, then s becomes ABCAC indexed 1,2,3,4,5.

Vingying wants to know the maximum number of operations (not the diamonds) he can do.

输入描述

The input contains a string consisting of only A,B,C representing the sequence of the diamonds. The length of the string won’t exceed 2×10^5.

输出描述
Output a single integer representing the maximum number of operations.

输入样例1:

ABCAAABCCC

输出样例1:

2

输入样例2:

AABCAAABCCC

输出样例2:

4

题意

给定一个只含有 ‘A’,‘B’,‘C’ 的字符串 下标从 1 开始 若 s[i]=‘A’ s[i+1]=‘B’ s[i+2]=‘C’
如果 i 是奇数可以删去 ‘AC’
如果 i 是藕数可以删去 ‘B’
问最大可以操作的次数

思路

显然若一个 ABC 删去 B 后就无法再操作
故可以贪心的删去尽量多的 AC
而删去 B 可以使后面的奇偶性改变
故对于一组 ABC 可以删的个数由两侧 AC 的个数以及前面删 B 的个数决定
后面分类讨论即可
i) 留下一对 AC 用于最后的删 B
ii)统计留下一对后AC对的对数
iii)计算能删的对数以及判断留下的最外侧 AC 的奇偶性以及使用过的前方 B 的个数来判断以下两种情况:1:剩下对偶数 直接删 B
2:剩下对奇数 若前方还有没用完的 B 翻转奇偶 删 B 否则
将最后一次也就是被翻转成奇数的偶数改为删 B 同时统计不删 AC 而去删 B 而节省的一次操作 即可能对未来没有增益的 B
3:若没有已经做过翻转操作以及前方也没有没有使用过的 B 只能删去 AC
iiii) 每一步统计溢出的 B
若该步没有溢出则清零之前所有节省的 AC (既之前省下AC留出的B都有用)
因为只要有用省下的那 1 个都能使后面的至少多删 1 个 贡献必定大于等于 0
若最有仍有溢出则加上省下的 AC

Code

#include<bits/stdc++.h>
using namespace std;
#define __T int csT;scanf("%d",&csT);while(csT--)
const int mod=1e9+7;
const int maxn=1e5+3;

int n,ans;
string s;
struct node{
    int id,l,r;
};
vector<node> abc;
inline void sol()
{
    cin>>s;
    n=s.size();
    ans=0;
    abc.clear();
    int b=0;
    s.insert(0,"x");
    for(int i=0;i<n;++i)
    {
        if(s[i]=='A'&&s[i+1]=='B'&&s[i+2]=='C')
        {
            abc.push_back({i+1,i,i+2});
        }
    }
    int yc=1e9;
    int js=0;
    for(int i=0;i<abc.size();++i)
    {
        int ll=abc[i].l-1,rr=abc[i].r+1,cnt=0,us=0;
        while(ll>=1&&s[ll]=='A'&&rr<=n&&s[rr]=='C')
        {
            ++cnt;
            --ll;
            ++rr;
        }
        if(cnt==0)
        {
            if(abc[i].l%2==0)
            {
                ++b;
                ++ans;
            }
            else
            {
                if(b>0)
                {
                    us=1;
                    ++b;
                    ++ans;
                }
                else ++ans;
            }
            if(i!=0)yc=min(yc,b-us);
            if(yc==0)js=0;
            continue;
        }
        if(abc[i].l%2==1)
        {
            --cnt;
            ++ans;
        }
        //ou
        us=min(cnt,b);
        ans+=us;
        if(us%2==0)
        {
            ++ans;
            ++b;
        }
        else
        {
            if(us<b)
            {
                ++ans;
                ++b;
                ++us;
            }
            else
            {
                if(us>0&&i!=abc.size()-1)
                {
                    --us;
                    ++js;
                    ++b;
                }
                else ++ans;
            }
        }
        if(i!=0)yc=min(yc,b-us);
        if(yc==0)js=0;
    }
    if(yc>0)ans+=js;
    printf("%d\n",ans);
}
int main()
{
    //__T
        sol();
    return 0;
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

柯西可乐

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值