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