pat B1040/A1093 有几个PAT

题目链接

要看题的点进去吧
这里直接说思路和代码。

思路

直接暴力会超时。

换个角度思考问题,对一个确定位置A来说,以它形成的PAT个数等于它左边P的个数乘以它右边T的个数。例如字符串APPAPT的中间那个A来说,它左边有两个P,右边有一个T,因此这个A能形成的PAT个数就是2X1=2。于是问题就转化为,对字符串中间的每个A,计算它左边P的个数与它右边T的个数的乘积,然后把所有的A的这个乘积相加就是答案。

那么,有没有比较快的获得每一位左边P的个数的方法呢?当然有,只需要设定一个数组leftNumP,记录每一位左边P的个数(含当前位,下同)。接着从左到右遍历字符串,如果当前位i是P,那么leftNumP[i]就等于leftNum[i-1]加一;如果当前位i不是P那么leftNumP[i]就等于leftNumP[i-1]。于是只需要O(len)的时间复杂度就能统计出leftNumP数组。

同样的方法可以计算出每一位右边T的个数。为了节省代码量,不妨在统计每一位右边个数T的过程中直接计算出答案ans。

具体做法是:定义一个变量rightNumT,记录当前累计的右边T个数。从右往左遍历字符串,如果当前位i是T,那么令rightNum加1;否则,如果当前位i是A,那么令ans加上leftNumP[i]与rightNumT的乘积(注意取模)。这样,当遍历完字符串时,就得到了答案ans

代码的变量名可能与上述变量有出入

AC代码:

#include<cstdio>
#include<cstring>
int main()
{
    char str[100010];
    scanf("%s",&str);
	int n = strlen(str);
	int a[n] = {0};
    for(int i = 0 ; i < n ; i++)
    {
        if(i>0)
            a[i]=a[i-1];
        if(str[i]=='P')
            a[i]++;
    }
	int ans=0,rightnum=0;
    for(int i = n - 1;i>=0;i--)
    {
        if(str[i]=='T'){
            rightnum++;}
        else if(str[i] == 'A')
        {
            ans = (ans+a[i]*rightnum) % 1000000007;
        }
	}
	printf("%d",ans);
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值