Sample Input:
APPAPT
Sample Output:
2
首先这道题看运行时间限制就知道肯定不能三重循环暴力求解,最后三个测试点直接运行超时。
于是想减少一层循环,具体思路是:外层循环循环整个字符串,并记录目前已经访问的‘P’的个数,一旦遇到‘A’,开始进入里层循环,里层循环是找当前‘A’往后到结尾的‘T’的个数。然后子串个数’= 左边‘P’的个数 * 右边‘T’的个数
有多少个‘A’,就有多少个 左边‘P’的个数 * 右边‘T’,即可得到答案。
但经过测试,还是会超时。。。
于是就只能有一层循环了:
具体思路和两层的思路差不多:先遍历一次串S,记录第一次‘A’的出现位置 pos,并记录它左边P的个数
for(int i=0;i<s.length()-1;i++){
if(s[i]=='P')
leftP++;
if(s[i]=='A'){
pos=i;
break;
}
}
然后再遍历一次串S,记录pos后的‘T’的个数
for(int i=pos+1;i<s.length();i++){
if(s[i]=='T')
rightT++;
}
最后再遍历一次,从pos+1开始,如果遇到‘P’,leftP(左边的P)个数+1,;如果遇到‘T’,右边的T减1;如果遇到A,直接计数一次count+=leftP*rightT;
全部代码:
#include <bits/stdc++.h>
using namespace std;
int main(){
string s;
cin>>s;
long long count=0;
int leftP=0;
int rightT=0;
int pos;
for(int i=0;i<s.length()-1;i++){
if(s[i]=='P')
leftP++;
if(s[i]=='A'){
pos=i;
break;
}
}
for(int i=pos+1;i<s.length();i++){
if(s[i]=='T')
rightT++;
}
count+=leftP*rightT;
for(int i=pos+1;i<s.length()-1;i++){
if(s[i]=='P')
leftP++;
else if(s[i]=='T')
rightT--;
else if(s[i]=='A'){
count+=leftP*rightT;
}
}
cout<<count%1000000007;
}
最后还有一个问题,如果最后两个测试点没过,是因为count要用long long