G. ABBC или BACB G. ABBC 或 BACB题解
- 链接:[https://codeforces.com/contest/1873/problem/G]
题目大意:
给定 是由字符 A和 B组成的 s 字符串。一开始,你没有硬币。你可以执行两种作:
- 选择一个 †AB子字符串,替换为 BC,然后获得一枚硬币。
- 选择一个 †BA子字符串,替换为 CB,然后获得一枚硬币。
问:最多能获得多少硬币
初步分析:
举例s字符串为ABBA,AB变为BC BA变为CB,发现没有?无论怎样变A必定消失,因此原问题可以转化为最多可以消多少个A
对于试例AAAAABBAAAA,将第一个AB变为BC此后前面的A也全会被消,后面的BA也是同理;
因此可以得出一个B可以把前面或者后面的连续A消掉
或者说 一个B可以把一串连续的A消掉(只不过消前面还是后面罢了)
思考解法:
依据初步分析最后一句话可以得出:
若B的个数>=连续A串个数 则可以将所有A全部消掉;
反之则不行,(说明必有一串A或多串A不能被消掉,那为什么不让他为最短的那几串呢)
所以 当B的个数<A串个数 则 少几个就剪几个A串个数的;
代码:
#include <bits/stdc++.h>
#define int long long
using namespace std;
signed main()
{
int t;
cin>>t;
while(t--)
{
string s;
cin>>s;
int n=s.size();
vector <int> vr;
int cnt=0,cnu=0,cns=0,o=0;
for(int i=0;i<n;i++)
{
if(s[i]=='A' && i==n-1)
{
cnt++;
cns+=cnt;
vr.push_back(cnt),o++;
}else if(s[i]=='A') cnt++;
else if(s[i]=='B' )
{
cnu++;
if(cnt>0) vr.push_back(cnt),o++;
cns+=cnt;
cnt=0;
}
}
sort(vr.begin(),vr.end());
for(int i=0;i<o-cnu;i++)
{
cns-=vr[i];
}
cout<<cns<<endl;
}
return 0;
}
注释:1.当遇到BAAAAA时最后不会触发if(s[i]==‘B’)不会记录最后一个A串,所以特判;
2.为什么特判cnt>0? 遇到ABBA,在第二个B时,多加了一个A串个数 同时cnt==0 vr数组也会多一个0 不对
反思:转化问题+菜就多练!!!
最后:如果对我有什么建议或是哪里错了
欢迎指出