题目链接
【题解】
这个题本来是看不懂的(在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;
}