链接:登录—专业IT笔试面试备考平台_牛客网
来源:牛客网
题目描述
给出一个长度为nnn的字符串SSS和一个长度为mmm的不含重复字符的字符串TTT,每次你可以在SSS中删除一个等于TTT的子序列,最多可以删除多少次?
如字符串S=ababccdS=ababccdS=ababccd,T=abcT=abcT=abc,可以选择s1s2s5,s1s2s6,s1s4s5,s1s4s6,s3s4s5,s3s4s6s_1s_2s_5,s_1s_2s_6,s_1s_4s_5,s_1s_4s_6,s_3s_4s_5,s_3s_4s_6s1s2s5,s1s2s6,s1s4s5,s1s4s6,s3s4s5,s3s4s6进行删除,删除后分别得到abcd,abcd,bacd,bacd,abcd,abcdabcd,abcd,bacd,bacd,abcd,abcdabcd,abcd,bacd,bacd,abcd,abcd。
如果删除后得到abcdabcdabcd,则还可以再进行一次删除,最多可以删除222次。
输入描述:
输入包含TSTSTS组测试用例,第一行一个整数TS(1≤TS≤10000)TS(1\le TS\le 10000)TS(1≤TS≤10000)。 对于每组测试用例: 第一行两个整数n,m(1≤n≤106,1≤m≤min(n,26),1≤∑n≤106)n,m(1\le n\le 10^6,1\le m\le min(n,26),1\le \sum n\le 10^6)n,m(1≤n≤106,1≤m≤min(n,26),1≤∑n≤106)。 第二行一个长度为nnn的字符串SSS。 第三行一个长度为mmm的字符串TTT。 S,TS,TS,T仅包含小写字母,输入保证对于任意i,j(1≤i<j≤m)i,j(1\le i<j\le m)i,j(1≤i<j≤m)满足Ti≠TjT_i\neq T_jTi=Tj。
输出描述:
输出TSTSTS行,第iii行一个整数为第iii组测试用例的答案。
示例1
输入
复制2 6 3 ababcc abc 9 3 aaabbbccc abc
2 6 3 ababcc abc 9 3 aaabbbccc abc
输出
复制2 3
2 3
这一题就是需要找到每一串完整的T序列然后记录下来,这里对于每一个环节,比如abc,在找b的时候实际上只需要找前面有没有a,找到是哪一个a实际上是无所谓的,所以只需要记录前面的a的个数,这里用num数组记录T中每个字母的个数,还有如何在找b的时候知道前面是什么呢,T中的字母顺序实际上是乱的,所以可以考虑用map把T中每一个字母对应成下标,这时候就可以很容易查询到前一个字母的数量了,num[i]的前一个就是num[i-1],找到一个b查询a的个数num[map[a]],如果有那么把b接上去,把a数量减1,所以num[x]实际上就是目前找到长度为x的子串的个数
#include<stdio.h>
#include<map>
using namespace std;
char s[110000];
char a[1000];
int num[1000];//记录字母的个数
int main()
{
int n, m, t; scanf("%d", &t);
while (t--)
{
scanf("%d%d", &n, &m);
scanf("%s%s", s + 1, a + 1);
map<char,int>mp;
for (int i = 1; i <= m; i++)
mp[a[i]] = i;
for (int i = 1; i <= n; i++)
{
if (s[i] == a[1])num[1]++;
else if (num[mp[s[i]] - 1])
{
num[mp[s[i]]]++;//有前继
num[mp[s[i]]-1]--;
}
}
printf("%d\n", num[mp[a[m]]]);
for (int i = 1; i <= m+1; i++)num[i] = 0;
}
return 0;
}