Problem Discription:
The string APPAPT
contains two PAT
's as substrings. The first one is formed by the 2nd, the 4th, and the 6th characters, and the second one is formed by the 3rd, the 4th, and the 6th characters.
Now given any string, you are supposed to tell the number of PAT
's contained in the string.
Input Specification:
Each input file contains one test case. For each case, there is only one line giving a string of no more than 105characters containing only P
, A
, or T
.
Output Specification:
For each test case, print in one line the number of PAT
's contained in the string. Since the result may be a huge number, you only have to output the result moded by 1000000007.
Sample Input:
APPAPT
Sample Output:
2
问题分析:
这题核心难点在于如何计算PAT的个数,以及用尽可能高效的方式处理这个问题。
PAT的个数计算方式为:A的左边P的个数与右边T的个数的乘积。
既然已经知道计算方式了,就要考虑如何高效计算的问题了。如果对字符串进行遍历,没找到个A,就去遍历A的左右PT的数量,那么必然是会超时的。所以,我们为了防止超时这个问题,就要通过“以空间换时间”的方式处理这个问题。再定义2个int类型的数组,用于存放A左边P和T的数量,那么遍历一次就可以把A左右的P、T数量得到了(A右边T的数量可以通过T的总数减去A的左边T的数量得到)。然后再对字符串中的A进行遍历,计算A左右PT的乘积和,最后别忘了对1000000007进行取模操作(题目中有提到,在output时,要mode一下)。
代码:
#pragma warning(disable:4996)
#include <stdio.h>
#include <string.h>
using namespace std;
char ch[100010];
int main()
{
scanf("%s", ch);
int n = strlen(ch);
int count = 0;
int left_P[100010], left_T[100010];
int T_num = 0,P_num=0;
for (int i = 0; i < n; i++)
{
if (ch[i] == 'P')
{
left_P[i] = ++P_num;
left_T[i] = T_num;
}
else if (ch[i] == 'T')
{
left_P[i] = P_num;
left_T[i] = ++T_num;
}
else
{
left_P[i] = P_num;
left_T[i] = T_num;
}
}
int i = 1;
while (i < n)
{
if (ch[i] == 'A')
count = (count + left_P[i] * (T_num - left_T[i])) % 1000000007;//这里需要取模,不要漏了
i++;
}
printf("%d", count);
return 0;
}