硬跑要T,所以用二分查
大概题意:在大字符串里面找到小字符串里面的每个字符需要买多少个字符;
思路:用二维数组标记下每个字符在每个下标位置之前出现过几次(前缀和),小字符串里面的每个字符所需要的数量用x[26]存下来,然后跑每个字符,找最小下标位置能满足每个字符串数量都得到过。(不能直接跑循环,要T)
(其实这道题我感觉我自己的第一遍代码能过,但是WA了第四组样例,我甚至找不出错误。。。难受,还是自己太菜了,这道题3K多人A了,很多都用vector写的,但是我还没用过vector,这周练习一下)
AC代码:
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
ll a[30][200010];
int main()
{
ll n;
cin>>n;
string s;
cin>>s;
for(int i=0;i<30;i++)
{
for(int j=0;j<n;j++)
a[i][j]=0;
}
for(int i=0;i<n;i++)
a[s[i]-'a'][i]++;
for(int i=0;i<30;i++)
{
for(int j=1;j<n;j++)
a[i][j] =a[i][j]+a[i][j-1]; ///
}
ll m;
cin>>m;
ll xx[30];
int ans;
while(m--)
{
string hh;
cin>>hh;
ll len=hh.length();
ll r= n-1;
ll l = 0;
ll ans = n-1;
for(int i=0;i<30;i++)
xx[i] =0;
for(int i=0;i<len;i++)
xx[hh[i]-'a']++;
while(l<=r)
{
ll mid=(l+r)/2;
int flag = 1;
for(int i=0;i<30;i++)
{
if(xx[i]>a[i][mid])
flag = 0;
}
if(flag==1)
{
ans = min(ans,mid);
r=mid-1;
}
else
l=mid+1;
}
printf("%d\n",ans+1);
}
return 0;
}