题目链接:http://codeforces.com/contest/779/problem/D
题目大意:给定两个字符串t和p,还有一个数组a[],按照a[]的顺序删减字符串t中的字母,保证字符串p是删减后的字符串字串,求能删减的最多字母。
分析:二分枚举a[],遍历寻找在剩余串中是否能找到p,具体分析详见代码注释。
自己在做CF时,整体思路就是错的,一直在想用什么容器存可以直接删除某个元素,然后直接用函数查找字串,事实证明这个思路是行不通的,然后这题就GG了,虽然写过二分的题目,但对二分运用的还不是那么娴熟。。。
#include<stdio.h>
#include<algorithm>
#include<string.h>
#include<iostream>
#include<stdlib.h>
#include<math.h>
#include<queue>
#include<map>
#include<stack>
using namespace std;
#define mann 200010
#define INF 0x3f3f3f3f
#define Max 1e14+10
typedef long long LL;
char s1[mann],s2[mann];
int a[mann],vis[mann];
int main()
{
while(~scanf("%s%s",s1+1,s2+1))
{
int len1=strlen(s1+1);
int len2=strlen(s2+1);
// printf("%d*%d \n",len1,len2);
for(int i=1; i<=len1; i++)
scanf("%d",&a[i]);
int l=1,r=len1,mid;
while(l<=r)//二分查找
{
int flag=0;
memset(vis,0,sizeof(vis));
mid=(l+r)>>1;
for(int i=1; i<=mid; i++)
vis[a[i]]++;
int k=1;
for(int i=1; i<=len1; i++)
{
if(!vis[i]&&s1[i]==s2[k])//遍历寻找剩余串中是否还包含字符串s2
k++;
if(k>len2)//在去掉a[l,mid]区间内对应s1的字符还能找到字符串s2
{
flag=1;
break;//标记之后跳出循环
}
}
if(flag)//增大删减范围
l=mid+1;
else//否则缩小删减范围
r=mid-1;
}
printf("%d\n",r);
}
}