F
一道双指针的好题
打ri和le两个指针,满足整除ri++,否则le到ri的位置
ri++,累加果子数量,超过k就删
#include<iostream>
#include<string>
#include<vector>
#include<algorithm>
#include<climits>
#include<cmath>
using namespace std;
using ll=long long;
const int M=2e5+9;
int b[M];
int pre[M];
void solve()
{
int n,k;cin>>n>>k;
vector<ll>a(n+3),b(n+3);
for(int i=1;i<=n;i++)cin>>a[i];//水果数量
for(int i=1;i<=n;i++)cin>>b[i];//树的高度
int ri,le;//双指针
ri=1;le=1;
ll t=0;//摘的果子
int ans=0;
while(ri<=n&&le<=n){
if(ri!=le&&b[ri-1]%b[ri]!=0){
t=a[ri];
le=ri;
ri++;
}else{
t+=a[ri];
ri++;
}
while(le<ri&&t>k){
t-=a[le];
le++;
}
ans=max(ans,ri-le);
}
cout<<ans<<'\n';
}
int main()
{
ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
int t;cin>>t;
while(t--){
solve();
}
return 0;
}
G
练思路的好题,观察可以发现每碰到一个B可以消去一串连续的A,得到A的数量个硬币,所以思路就简单了,我们记下离散的B的数量,记下连续的A的段数,如果A的段数多余B的数量,则答案为A的总数减去A连续最小的段的A的数量,如果小于等于,则答案为所有A的数量
#include<iostream>
#include<string>
#include<vector>
#include<algorithm>
#include<climits>
#include<cmath>
using namespace std;
using ll=long long;
const int M=2e5+9;
int b[M];
int pre[M];
void solve()
{
string str;cin>>str;
int n=str.size();
vector<int>a;
for(int i=0;i<n;i++){
int num=0;
while(str[i]=='A'){
i++;
num++;
}
a.push_back(num);
}
int ans=0;//记录A的数量
int bns=0;//记录B的数量
for(auto x:str)
if(x=='B')bns++;
for(auto y:str)
if(y=='A')ans++;
if(bns>=a.size())cout<<ans<<'\n';
else {
sort(a.begin(),a.end());
cout<<ans-a[0]<<'\n';
}
}
int main()
{
ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
int t;cin>>t;
while(t--){
solve();
}
return 0;
}