子串查询Time Limit: 3500/3000 MS (Java/Others) Memory Limit: 262144/262144 K (Java/Others)Total Submission(s): 382 Accepted Submission(s): 200 Problem Description 度度熊的字符串课堂开始了!要以像度度熊一样的天才为目标,努力奋斗哦!
Input 第一行包含一个整数 T,表示有 T 组测试数据。
Output 对于每组测试数据,先输出一行信息 "Case #x:"(不含引号),其中 x 表示这是第 x 组测试数据,接下来 q 行,每行包含一个整数,表示字符串 A[l,r] 中字典序最小的子串个数,行末不要有多余空格。
Sample Input 1 2 3 AB 1 1 1 2 2 2
Sample Output Case #1: 1 1 1 Source |
题目分析
求字符串 A[l,r] 中字典序最小的子串个数,首先要明确一点
单个字符的要比多个字符要小
所以这个问题就可以转化为在字符串A[l,r]中个字典序最小的字母有多少。
例如
A[5]={A,B,A,A,B}
A[2,3]=2(B,A,A,中A最小,且个数为2)
根据这种情况我想到了前缀和的方式。
废话不多说了,直接代码
#include<iostream>
#include<cstring>
using namespace std;
const int maxn=100000+10;
int a[maxn][30];
int main(){
ios::sync_with_stdio(false);
int T,Case=1;
cin>>T;
while(T--)
{
int len,q,l,r;
char x;
cin>>len>>q;
for(int i=1;i<=len;i++){
cin>>x;
for(int j=0;j<26;j++)//前缀和处理
a[i][j]=a[i-1][j];
a[i][x-'A']++;
}
cout<<"Case #"<<Case++<<":"<<endl;
for(int i=0;i<q;i++){
cin>>l>>r;
int j;
for(j=0;j<26;j++){
if(a[r][j]-a[l-1][j]==0) continue;
break;
}
cout<<a[r][j]-a[l-1][j]<<endl;
}
}
return 0;
}
虽然已经过了,但是效率有点慢,希望哪位大佬路过时可以给我指点一下O(∩_∩)O~~