几个重点:
1、首先采用在线的方法将读入的数据直接处理,而不是全部读入后再进行操作。
2、针对大规模的数据,需要一个比较优化的算法,出现O(n2)要做好优化,否则最后两个检查点不通过。
3、对于题目要做好充分理解,将抽象问题化为可以执行的算法。
4、配合适当的图解和手动运算,可以充分模拟算法的运行情况,减少编码后的调试工作。
演示:
其中,P_arr存储每个A左侧的P的个数,下标为A的位置,值为P的个数;T_arr原用于存储每个A右侧T的个数,后来发现如果每次读入T都去更新当前位置之前的每一个值,会使复杂度到达O(n2),导致超时,故只存储读入的T的个数,之后用最大的T值减去每个位置的T值即可得到当前A右侧的T的个数。在算法的最后只需要将两者相乘,即可得到每个A产生的PAT个数。笔者文笔有限,如果看不懂请结合图示和代码。
代码:
(CSDN的排版稍微有些问题,建议拷到editor观看。)
#include "stdlib.h"
#include "stdio.h"
#include "string.h"
int main(){
int P_arr[100010],T_arr[100010],P=0,i,N=0,MAX_T=0;
long long sum=0; // 注意该数字可能很大
char input;
memset(P_arr,0,sizeof(P_arr));
memset(T_arr,0,sizeof(T_arr));
while(1){
input = getchar();
if(input == 'P')
break;
}
while(1){
if(input == 'P'){
P_arr[P] ++;
}else if(input == 'A'){
// 遇见A则形成一组PA,P_arr增加一个单元,且累加前面P的个数
P++;
P_arr[P] += P_arr[P-1];
T_arr[P] += T_arr[P-1];
}else{
if(P!=0){
T_arr[P] += 1; // 遇到T则增加一个T的数量,注意这里存储的T数量不能直接使用
MAX_T = T_arr[P];
}
}
input = getchar();
if(input == EOF || input == '\n'){
break;
}
N++;
}
for(i=0;i<P;i++){
sum += P_arr[i] * (MAX_T - T_arr[i]); // 用MAX_T减去T的数量是因为每一组内T的真实数量正好与存储的数量互补为NAX_T
}
sum %= 1000000007;
printf("%lld",sum);
return 0;
}