前言:这个题不算难题,但是限时150ms,如果暴力解法很容易超时。所以必须想其他办法。而最开始经验不丰富(菜)的我尝试了多重循环法,如愿以偿三个测试点都超时。查询其他大佬解法后才AC
超时解法= =
#include<iostream>
using namespace std;
char arr[100010];
int main()
{
long long num = 0;
cin >> arr;
char* p = arr;
char* tmp1 = p;
char* tmp2 = p;
char* tmp3 = p;
int flag = 1;
while (*p != '\0')
{
tmp1 = p;
if (*tmp1 == 'P')
{
int flag = 0;
p++;
// AP PA APTTATTAAATATATTTAAT
for (tmp2 = tmp1 + 1; *tmp2 != '\0'; tmp2++)
{
if (*tmp2 == 'A')
{
for (tmp3 = tmp2 + 1; *tmp3 != '\0'; tmp3++)
{
if (*tmp3 == 'T')
{
flag = 1;
num++;
}
}
}
}
}
else
{
p++;
continue;
}
if (!flag)
{
break;
}
}
cout << num % 1000000007;
return 0;
}
某柳姓大神的解法(实在NB)
#include<iostream>
using namespace std;
int main()
{
string s;
cin >> s;
int len = s.length();
long long countp = 0, countt = 0;
long long num = 0;
for (int i = 0; i < len; i++)
{
if (s[i] == 'T')
countt++;
}
for (int i = 0; i < len; i++)
{
if (s[i] == 'P')
countp++;
if (s[i] == 'T')
countt--;
if (s[i] == 'A')
num += countp * countt;
}
cout << num % 1000000007;
return 0;
}
即:PAT的个数为每个A字符左P和右T的相乘的和
第三种AC解法:
#include<iostream>
#include<cstring>
using namespace std;
char arr[100010];
int main()
{
cin >> arr;
int len = strlen(arr);
long long t = 0, at = 0, pat = 0;
for (int i = len - 1; i >= 0; i--)
{
if (arr[i] == 'T')
t++;
if (arr[i] == 'A')
at += t;
if (arr[i] == 'P')
pat += at;
}
cout << pat % 1000000007;
return 0;
}
反向遍历,遇到 ’T‘,则T的个数+1,遇到A。 AT的个数就是此时T的个数加上之前的AT的个数。 遇到P。PAT的个数就是当前AT的个数加上之前PAT的个数;(正向也可以)
其实这个题就是判断每一个P后面有多少个AT。就看如何计数了(难得是如何能想到这个规律与计数方法。)