D. String Game 二分加字符串匹配
题目大意:给出字符串str1,再第二行给出字符串str2,第三行给出删除str1中的字符的顺序,用数组a[]存,问最多按第三行的顺序删除str1中的字符剩下的字符串中str2
我们定义l为a[]的左边界,r为a[]的右边界,mid为a[]的中
我们要求的是最多能删除的字符数,那么mid的值越大越好,所以首先判断mid~r中剩下的字符包括str2吗?
如果包括包括我们令l=mid,看看mid可不可能取更大的值
如果不包括我们令r=mid(所以r永远不可能是mid的取值,及区间为左闭右开),降低mid的取值。
代码实现:
1 #include<iostream>
2 #include<cstdio>
3 #include<cmath>
4 #include<algorithm>
5 #include<cstring>
6 #include<vector>
7 #include<map>
8 #define ll long long
9 using namespace std;
10 int a[200005],b[200003];char str1[200005],str2[200005];
11 int r,l,L;
12 int judge(int m)
13 {
14 int k=0;
15 for(int i=m;i<L;i++)
16 b[k++]=a[i];
17 sort(b,b+k);
18 m=0;
19 for(int i=0;i<k;i++)
20 {
21 if(str1[b[i]-1]==str2[m])//第三行数字是从1开始的
22 m++;
23 }
24 if(m==strlen(str2))
25 return 1;
26 else
27 return 0;
28 }
29 int main()
30 {
31 int n,mid,i,k,ans,j;
32 while(cin>>str1>>str2)
33 {
34 L=strlen(str1);
35 for(i=0;i<L;i++)
36 scanf("%d",&a[i]);
37 l=0;r=L;
38 while(r-l>1)
39 {
40 mid=(l+r)>>1;
41 if(judge(mid))
42 {
43 // printf("mid1=%d\n",mid);
44 l=mid;
45 }
46 else
47 {
48 // printf("mid2=%d\n",mid);
49 r=mid;
50 }
51 }
52 printf("%d\n",l);
53 }
54 return 0;
55 }