字符串 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
思路:
思路一:暴力求解,两层for循环,第一层遇到P之后进入第二层for循环,第二层for循环遇到A停,此时判断T出现的次数,若T出现的次数不为0,则sum+=f3;(f3代表第二层的A之后T出现的次数)。意料之中的超时。
代码如下:
#include <bits/stdc++.h>
using namespace std;
int main(){
char a[100100];
int t1 = 0,t2 = 0,t3 = 0;
long long int sum = 0;
scanf("%s",a);
for(int i = 0;i < strlen(a);i++){
if(a[i] == 'P')
t1++;
else if(a[i] == 'A')
t2++;
else if(a[i] == 'T')
t3++;
}
for(int i = 0;i < strlen(a);i++){//第一层for循环遇到P进入第二层循环
if(a[i] == 'P'){
if(t2 != 0&&t3 != 0){
int f2 = t2,f3 = t3;
for(int j = i+1;j < strlen(a);j++){//第一层for循环遇到A后判断此时A之后T的个数
if(a[j] == 'A'){
if(f3 != 0){
sum = (sum + f3)%1000000007;//PAT出现的次数
}
f2--;
}
else if(a[j] == 'T')
f3--;
}
}
t1--;
}
else if(a[i] == 'A')
t2--;
else if(a[i] == 'T')
t3--;
}
printf("%lld\n",sum%1000000007);
return 0;
}
思路二:(参考大佬思路:https://www.jianshu.com/p/65291de1906b)
从前向后扫描:
- 每个A对应的PA组合数量是A之前P的数量,
- 每个T对应的PAT组合数量是T之前所有A对应的PA组合数量的累加,
- 所有的PAT组合数量是所有T对应的PAT组合数量的累加
代码实现:
#include <bits/stdc++.h>
#define LIM 1000000007
using namespace std;
int main(){
int P = 0, PA = 0, PAT = 0;
char c;
while((c = getchar()) != '\n')
{
if(c == 'P') P++;
if(c == 'A') PA = (PA + P) % LIM;
if(c == 'T') PAT = (PAT + PA) % LIM;
}
printf("%d", PAT);
return 0;
}