1. 程式人生 > >PAT乙級 1040 有幾個PAT

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;
}

在這裡插入圖片描述