String Game

二分答案的练手题,虽然很淼,但本题解提供一种清爽的解。

  1. 首先,二分什么:

当然是二分可以删除的次数,并使用 check 函数判断该值是否合法。这点毋庸置疑。

  1. 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;
}
posted @ 2023-03-12 07:14  shoot_down  阅读(9)  评论(0)    收藏  举报  来源