题目描述
字符串APPAPT中包含了两个单词“PAT”,其中第一个PAT是第2位§,第4位(A),第6位(T);第二个PAT是第3位§,第4位(A),第6位(T)。
现给定字符串,问一共可以形成多少个PAT?
输入描述:
输入只有一行,包含一个字符串,长度不超过105,只包含P、A、T三种字母。
输出描述:
在一行中输出给定字符串中包含多少个PAT。由于结果可能比较大,只输出对1000000007取余数的结果。
输入例子:
APPAPT
输出例子:
2
思路1:这道题可以倒着看,T之前的A的数量可以得到AT的数量(这里注意A前一定要有P),A之前P的数量可以得到PA的数量,因此PAT的数量应该是A之前P的数量之和和T之前A的数量之和的积。
时间超时
#include<iostream>
#include<string>
#include<map>
using namespace std;
int main(){
string s;
cin>>s;
int n=0,j=0,k=0,h=0,num=0;
map<int,int>p,a,t;
for(int i=0;i<s.size();i++)
{
if(s[i]=='P')
p[j++]=i;
else if(s[i]=='A')
a[k++]=i;
else if(s[i]=='T')
t[h++]=i;
}
for(int i=0;i<j;i++)
{
for(int i1=0;i1<k;i1++)
{
for(int i2=0;i2<h;i2++)
if(p[i]<a[i1] && a[i1]<t[i2])
num++;
}
}
cout<<num%1000000007;
return 0;
}
思路2:
从前向后扫描:
- 每个A对应的PA组合数量是A之前P的数量,
- 每个T对应的PAT组合数量是T之前所有A对应的PA组合数量的累加,
- 所有的PAT组合数量是所有T对应的PAT组合数量的累加
#include<iostream>
#include<string>
using namespace std;
int main()
{
string strPAT;
cin>>strPAT;
int istr=0,P=0,PA=0,PAT=0;
while(istr<strPAT.size())
{
if('P'==strPAT[istr]) P++;
else if('A'==strPAT[istr]) PA+=P;
else{ // if('T'==strPAT[istr])
PAT+=PA;
PAT=PAT%1000000007;
}
istr++;
}
printf("%d",PAT);
return 0;
}
}