String Game
二分答案的练手题,虽然很淼,但本题解提供一种清爽的解。
- 首先,二分什么:
当然是二分可以删除的次数,并使用 check 函数判断该值是否合法。这点毋庸置疑。
check怎么写。
首先,我们假设可以删除 $m$ 次。使用标记数组将 $a_1$ 到 $a_m$,所表示的字符串下标,置为不可使用。
然后拟定一个字符串 $b$ 的下标 $c$,遍历字符串 $a$,若 $b_c$ 与字符串 $a$ 当前位置上的字符相同,则 c++。
若 c=b.size 则该 $m$ 是合法的。反之,不合法。
代码:
#include<bits/stdc++.h>
using namespace std;
string a,t;
int b[200001];
bool f[200001];
int sizea,sizet;
bool check(int m){
memset(f,0,sizeof f);//一定要清零。
for(int i=1;i<=m;i++) f[b[i]-1]=1;//题中给出的下标是从1开始的,但字符串的下标是从0开始的,所以要-1。
int cnt=0;
for(int i=0;i<sizea;i++){
if(!f[i]&&a[i]==t[cnt]) cnt++;//若相等,个数加一
if(cnt==sizet) return 1;//合法。
}
return 0;
}
int main()
{
cin>>a>>t;
sizea=a.size();
sizet=t.size();
for(int i=1;i<=sizea;i++){
cin>>b[i];
}
int l=0,r=sizea,mid,ans=0;
while(l<=r){
mid=(l+r)/2;
if(check(mid)){
ans=mid;
l=mid+1;
}
else r=mid-1;
}
cout<<ans;
return 0;
}

浙公网安备 33010602011771号