首页 > 技术文章 > D. String Game 二分加字符串匹配

WHLdbk 2017-03-01 21:08 原文

题目链接

题目大意:给出字符串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 }

 

推荐阅读