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;
}

 
                
            
         浙公网安备 33010602011771号
浙公网安备 33010602011771号