1040. 有几个PAT(25)

本文介绍了一种算法,用于计算给定字符串中可以形成的PAT数量。通过遍历字符串并统计每个A左侧的P与右侧的T的数量,从而得出总的组合数量,并确保结果在1000000007范围内。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1040. 有几个PAT(25)
时间限制 120 ms 内存限制 65536 kB 代码长度限制 8000 B
判题程序 Standard 作者 CAO, Peng

字符串APPAPT中包含了两个单词“PAT”,其中第一个PAT是第2位(P),第4位(A),第6位(T);第二个PAT是第3位(P),第4位(A),第6位(T)。
现给定字符串,问一共可以形成多少个PAT?
输入格式:
输入只有一行,包含一个字符串,长度不超过105,只包含P、A、T三种字母。
输出格式:
在一行中输出给定字符串中包含多少个PAT。由于结果可能比较大,只输出对1000000007取余数的结果。
输入样例:
APPAPT
输出样例:
2

思路一:对于每一个A,可以组成pat的为A左边的P的个数与A右边T的个数,所以统计所有的A能组成的个数对1000000007求余即可

#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <cstring>
#include <fstream>
#include <string>
#include <cmath>
#include <algorithm>
#include <queue>
#include <map>
using namespace std;

const int MaxN = 100010;

int main()
{
#ifdef _DEBUG
    freopen("data.txt", "r+", stdin);
    //fstream cin("data.txt");
#endif // _DEBUG

    char str[MaxN];
    int ALeftP[MaxN] = { 0 };
    long long res = 0;
    int countT = 0;

    scanf("%s", str);
    ALeftP[0] = (str[0] == 'P');

    for (int i = 1; str[i]; ++i)
    {
        if (str[i] == 'P')
            ALeftP[i] = ALeftP[i - 1] + 1;
        else
            ALeftP[i] = ALeftP[i - 1];
    }

    for (int i = strlen(str) - 1; i >= 0; --i)
    {
        if (str[i] == 'T') ++countT;
        else if (str[i] == 'A')
            res =  (res + ALeftP[i] * countT) % 1000000007;
    }

    printf("%lld", res);

#ifdef _DEBUG
    //cin.close();
#ifndef _CODEBLOCKS
    std::system("pause");
#endif // !_CODEBLOCKS
#endif // _DEBUG

    return 0;
}
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <fstream>
#include <string>
#include <cmath>
#include <algorithm>
#include <queue>
using namespace std;


int main()
{
#ifdef _DEBUG
    freopen("data.txt", "r+", stdin);
    //fstream cin("data.txt");
#endif // _DEBUG

    const int MaxN = 100010;
    char str[MaxN];
    int P = 0, A = 0, T = 0;
    unsigned long long C = 0, Mod = 1000000007, CP = 0,CA = 0, CT = 0;;
    scanf("%s", str);
    for (; str[T]; ++T)
    {
        while (str[T] != 'T' && str[T])++T;//找到尚未利用的T;
        if (!(str[T] == 'T'))
            break;
        for(;A < T && str[T];++A)
        {

            while (A < T && str[A] != 'A')++A;//掠过不是A的字符
            if (!(str[A] == 'A'))
                break;
            for (;P < A;++P)
            {
                if (str[P] == 'P')
                    ++CP; // 当前字母是P,可以组成PAT,P的数量加1
            }
            CA = CP % Mod;//此处为当前所指的A左边有多少个P,即有CP总组成方式
            CT += CA;//当前T有所有A的组成方法之和总组成方式
        }
        CT %= Mod;
        C = (CT + C) % Mod;//当前T加上之前的组成方法即为总的组成方式
    }

    printf("%lld", C);


#ifdef _DEBUG
    //cin.close();
#ifndef _CODEBLOCKS
    system("pause");
#endif // !_CODEBLOCKS
#endif // _DEBUG

    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值