【HDOJ 5056】 Boring count (排列组合)
我的做法是两个指针 一个指向最后匹配好的字符的后一位 一个沿字符串遍历 开个数组标记每个字母出现过的次数 当遍历到某个字母 出现次数>k时 从j往后找j后面第一次出现该字符的位置 可知从此位置往前的字符都无法遍历到当前的i 因此把此位置及之前与i之前能组成的子串统计一下 这样不断的遍历 最后输出即为答案
代码如下:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <queue>
using namespace std;
#define ll long long
int num[26];
char str[100002];
int main()
{
int t,k,i,j,id;
ll sum;
int ch;
scanf("%d",&t);
while(t--)
{
memset(num,0,sizeof(num));
scanf("%s %d",str,&k);
sum = 0;
id = 0;
for(i = 0; str[i]; ++i)
{
ch = str[i]-'a';
num[ch]++;
if(num[ch] > k)
{
j = id;
num[ch]--;
while(str[id] != ch+'a')
{
num[str[id]-'a']--;
id++;
}
sum = sum+(ll)(i-j)*(i-j+1)/2-(ll)(i-id-1)*(i-id)/2;(统计由从j到j之后第一次出现该字符的这些字符为首的子串个数)
id++;
}
}
sum += (ll)(i-id)*(i-id+1)/2;//累计上最后的子串
printf("%I64d\n",sum);
}
return 0;
}