注解
1、分析题目可知,字典序最小的一定只包含一个字母,且是这个区间内所含字母的字典序最小的那个。因此,题目也就是问,给定一个字符串,在某个区间内,字典序最小的那个字符出现了多少次。
2、前缀和的思想。cnt[i]表示从第1到第i个位置出现的某个字符数。为了统计26个字符,因此cnt是二维数组,第二维表示按字典顺序的排序,从a到z。这样遍历的时候,只要找到某个不为0,就可以break了,这个就是字典序最小的字母出现的次数。
3、关键代码:
(1)memcpy(cnt[j+1], cnt[j], sizeof(cnt[j]));
cnt[j+1][c-‘A’]++;
(2)ans[k] = cnt[r][k] - cnt[l-1][k];
代码
#include <iostream>
#include <cstring>
using namespace std;
const int MAXN = 26;
int main(){
int T;
scanf("%d", &T);
for(int i=1; i<=T; i++){
int n, q;
scanf("%d%d", &n, &q);
int cnt[n+1][MAXN];
memset(cnt, 0 ,sizeof(cnt));
getchar();
for(int j=0; j<n; j++){
char c;
scanf("%c", &c);
memcpy(cnt[j+1], cnt[j], sizeof(cnt[j]));
cnt[j+1][c-'A']++;
}
printf("Case #%d:\n", i);
for(int j=0; j<q; j++){
int l, r;
scanf("%d%d", &l, &r);
int ans[MAXN];
for(int k=0; k<MAXN; k++){
ans[k] = cnt[r][k] - cnt[l-1][k];
if(ans[k]){
printf("%d\n", ans[k]);
break;
}
}
}
}
return 0;
}