PAT Basic 1040. 有几个PAT
PAT Basic 1040. 有几个PAT
1. 题目描述:
字符串 APPAPT
中包含了两个单词 PAT
,其中第一个 PAT
是第 2 位(P
),第 4 位(A
),第 6 位(T
);第二个 PAT
是第 3 位(P
),第 4 位(A
),第 6 位(T
)。
现给定字符串,问一共可以形成多少个 PAT
?
2. 输入格式:
输入只有一行,包含一个字符串,长度不超过\(10^5\),只包含 P
、A
、T
三种字母。
3. 输出格式:
在一行中输出给定字符串中包含多少个 PAT
。由于结果可能比较大,只输出对 1000000007 取余数的结果。
4. 输入样例:
APPAPT
5. 输出样例:
2
6. 性能要求:
Code Size Limit
16 KB
Time Limit
150 ms
Memory Limit
64 MB
思路:
最直接的思路是穷举所有可能进行统计,一开始以为能找规律通过排列组合算出来,但想不出来。。。
以下题解的思路是倒序遍历字符串,countT
统计'T'的个数,countAT
统计'AT'的个数,每遇到一次'A'就累加countT
到countAT
上,表示当前A'可以组合多少个'AT',然后每遇到一次'P',就累加countAT
到res
上,表示当前'P'可以组合多少个'PAT',最后返回结果res
。
这里还需要注意取余的处理,不能最后再进行取余,因为res
可能累加到一个比较大的值造成溢出。需要在每次累加res
时进行取余,两种操作是等价的,可以通过数学归纳法证明。
如果正序遍历字符串的话是比较麻烦的,这种倒序遍历反而比较简洁,只能说思路非常重要。这种题解的思路参考大佬的题解PAT-Basic-1040. 有几个PAT – Lnyan's Blog (llonely.com)
My Code:
#include <stdio.h>
#include <string.h>
#define MOD 1000000007
int main(void)
{
char words[100001] = "";
int countT = 0;
int countAT = 0;
int res = 0;
int i = 0; // iterate var
scanf("%s", words); // input the string
//size_t strlen(const char *str)
for(i = strlen(words)-1; i>=0; i--)
{
if(words[i] == 'T')
{
countT++;
}
else if(words[i] == 'A')
{
countAT += countT;
}
else // words[i] == 'P'
{
res += countAT;
res %= MOD; // do this way
}
}
// res %= MOD; // can't this way
printf("%d\n", res);
return 0;
}