【CF】【二分】String Game

题目链接

【题解】

这个题本来是看不懂的(在VJ上显示有误),后来在原题面上居然就看懂了,真的太过分了,少了最关键的一些标注。这个题目的意思是:一个妹妹喜欢把一个字串的某些位置拆卸下来,然后他的哥哥想让她做点有意义的事情,就让她拆卸下来能作为另外的一个子串。然后这个哥哥尽可能后地阻止她到某一个位置拆下来,因为哥哥知道她拆下来的次序。

可能看题意不太懂,看第一个事例的解释,其实就很明白了。

原串 t:ababcba

匹配p:abb

拆的过程是:

ababcba->ababba->abbba->abba->bba->bb->b->" "

然后哥哥在第三部就阻止了,剩下来的就是abba,让这个abba的子序列中包含abb。

明白题意了,然后我就迷糊了,想着是用什么string类的  类似与python的in.

然后想着LCS,

但是最后一个tag标签提示我了,这个时候用二分来选择。

为什么用二分呢?二分来选择到某个位置就停下来,然后就不再执行即可。

然后怎么判断呢???用一个for循环来判断。因为你选择的时候留下来的就是按顺序的排好,只需管好是否存在这么一个子序列即可。

所以二分做题:

贴上代码:

#include<bits/stdc++.h>
using namespace std;
const int N=2e5+100;
char t[N],p[N];
int n,m,len,a[N],vis[N];
bool check(int x){
    int ans=0;
    memset(vis,0,sizeof(vis));
    for(int i=1;i<=x;i++)
        vis[a[i]]=1;
    int cur=1;
    for(int i=1;i<=n;i++){
        if(!vis[i]&&t[i]==p[cur])
            cur++;
    }
    if(cur>m)
        return true;
    else
        return false;
}
int main()
{
    scanf("%s%s",t+1,p+1);
    n=strlen(t+1);
    m=strlen(p+1);
    len=strlen(t+1);
    for(int i=1;i<=n;i++){
        scanf("%d",&a[i]);
    }
    int ans,L=0,R=n,mid;
    while(L<=R){
        mid=(L+R)/2;
        if(check(mid)){
            L=mid+1;
            ans=mid;
        }else{
            R=mid-1;
        }
    }
    printf("%d\n",ans);
    return 0;
}

猜你喜欢

转载自blog.csdn.net/Z_sea/article/details/87180484