PAT乙级 1040 有几个PAT

字符串 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

思路:

三重循环完成计数。

代码:

#include<stdio.h>
#include<string.h>
int main(){
	char s[100001];
	scanf("%s",s);
	int len=strlen(s);
	long cnt=0;
	for(int i=0;i<len-2;++i){
		if(s[i]=='P'){
			for(int j=i+1;j<len-1;++j){
				if(s[j]=='A'){
					for(int k=j+1;k<len;++k){
						if(s[k]=='T'){
							++cnt; 
						}
					}
				}
			}
		}
	}
	printf("%ld",cnt%1000000007);
}

在这里插入图片描述

出现的问题:

测试点2、3、4运行超时,当前算法时间复杂度为O(n3),所以需要优化,或者改用其他方法。

第一次修改:

既然是要找出字符串中有多少个PAT,那么如果找到了A,PAT的个数即等于A左侧P的个数乘上A右侧T的个数。这样的话针对A做一次循环即可求解,时间复杂度为O(n)。

#include<stdio.h>
int main(){
	char ch,s[100001];
	int cnt_p=0,cnt_t=0,len=0;
	for(int i=0;(ch=getchar())!='\n';++i,++len){
		s[i]=ch;
		if(ch=='T'){
			++cnt_t; 
		}
	}
	long cnt=0;
	for(int i=0;i<len;++i){
		if(s[i]!='A'){
			if(s[i]=='P'){
				++cnt_p; 
			}
			else{
				--cnt_t; 
			}
		}
		else{
			cnt+=cnt_p*cnt_t;
		}
	}
	printf("%ld",cnt%1000000007);
	return 0;
}

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/qq_37205425/article/details/84110380