在比赛的时候这题没做出来。
因为感觉数据量太大,直接暴力的话会超时。
赛后看了下大神们的代码,发现是二分。
自己研究了下,中间错了好多次。
下面总结下这里的二分。
while(l<=r)
{
if(mids(MID(l,r)))
{
l=MID(l,r)+1;
}else{
r=MID(l,r)-1;
}
}
这里是二分的关键代码,注意每次都要 l+1 和 r-1 否则会出现死循环。
注意,最后输出答案的时候,l要减1,因为最后一次出while循环l会额外加1.
下面是ac代码
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<math.h>
#include<algorithm>
#include<map>
#include<set>
#include<queue>
#include<string>
#include<iostream>
using namespace std;
#define MID(x,y) ((x+y)>>1)
#define CLR(arr,val) memset(arr,val,sizeof(arr))
#define FAST_IO ios::sync_with_stdio(false);cin.tie(0);
const double PI = acos(-1.0);
const int INF = 0x3f3f3f3f;
const int N=2e5+7;
int l,r,n,len2,r2;
char b[200002];
char a[200002];
bool c[200002];
int d[200002];
bool mids(int mi)
{
CLR(c,false);
for(int i=1;i<=mi;i++)
{
c[d[i]]=true;
}
for(int i=1,j=1;i<=r2;i++)
{
if((!c[i])&&(a[i]==b[j]))
{
++j;
if(j>len2)
{
return true;
}
}
}
return false;
}
int main()
{
//freopen("f:/input.txt", "r", stdin);
int len1;
while(scanf("%s%s",a+1,b+1)!=EOF)
{
CLR(d,0);
r=strlen(a+1);
for(int i=1;i<=r;i++)
scanf("%d",&d[i]);
len2=strlen(b+1);
r2=r;
l=0;
while(l<=r)
{
if(mids(MID(l,r)))
{
l=MID(l,r)+1;
}else{
r=MID(l,r)-1;
}
}
printf("%d\n",l-1);
}
}