1040. 有幾個PAT(25) http://www.patest.cn/contests/pat-b-practise/1040
字符串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
原題: PAT(A) 101-125-1-2015-03-14 http://www.patest.cn/contests/pat-a-101-125-1-2015-03-14/B
The string APPAPT contains two PAT's as substrings. The first one is formed by the 2nd, the 4th, and the 6th characters, and the second one is formed by the 3rd, the 4th, and the 6th characters.
Now given any string, you are supposed to tell the number of PAT's contained in the string.
Input Specification:
Each input file contains one test case. For each case, there is only one line giving a string of no more than 105 characters containing only P, A, or T.
Output Specification:
For each test case, print in one line the number of PAT's contained in the string. Since the result may be a huge number, you only have to output the result moded by 1000000007.
Sample Input:
APPAPT
Sample Output:
2
這道題是2015年3月份的甲級PAT考試試題,不難,但是腦筋得活才能拿到滿分。
基本注意事項:
提供的字符串只可能包含'P'、'A'、'T'三種字符
長度不超過10的五次方,如果用字符數組的話,則字符串的長度至少是105+1(結束符'/0')
結果數據可能很大,需要及時的模(%=1000000007)處理
分析:
如果暴力解決,順序遍歷,時間復雜度為(10的五次方)的三次方,可能會超時,所以拿不到滿分;在想不到更優解時,可以這么干。
可以考慮組合排列的方法,逆序總結(可以遞歸實現)。
核心思路:如果有一個P出現,則只要知道后面有多少種AT可選,則這個P可以對應的PAT選擇方法就有多少種;AT類似。
啰嗦思路:組成PAT的條件有P在A前出現,A在T前出現 。
求PAT選擇的方法有多少種,則只要知道每個P對應的PAT選擇方法有多少種,求和即可;
每個P對應PAT種類取決於這個P的后面,有多少種AT可選(如果有一個P出現,則只要知道后面有多少種AT可選,則這個P可以對應的PAT選擇方法就有多少種)。
一個P后面有多少種AT可選,其實和這個字符串中多少種PAT可選是一個問題,即所有的A對應的AT選法的和;
一個A對應的AT種類取決於這個A后面有多少種T可選(如果有一個A出現,則只要知道后面有多少種T出現,則這個A對應的AT選擇方法就有多少種)。
eg:PPPAATTT
字符: P P P A A T T T
位置: 7 6 5 4 3 2 1 0
下標為7的P對應的PAT選法取決於后面字符串(PPAATTT)中AT的選法,其他P相應對應自己后面的字符串的AT選法;
下標為4的A對應的AT選法取決於后面字符串(ATTT)中的T的選法,另一個A相應處理;
下標為2/1/0的T進行不需要選擇了,因為一個T對應的T的選法就是自身;
代碼變量說明:
numAT表示當前已處理的字符串字串中T的選法,也就表明,如果處理一個字符是A,則這個字符A對應的AT的選法,就是numAT;
numPAT的理解相對應。
手工流程演示:位於下標5的P對應的PAT的選法有6種,來源於P后面的兩個A,下標4的A對應的AT有3種選法,下標3的A也是。
第二次刷題時的代碼 4月16日 17:15
1 #include<cstdio> 2 #include<cstring> 3 4 int main() 5 { 6 char strPAT[100010]; 7 gets(strPAT); 8 9 int istr=strlen(strPAT),numAT=0,numPAT=0,num=0; 10 while(istr--) 11 { 12 if('T'==strPAT[istr]) numAT++; 13 else if('A'==strPAT[istr]) numPAT+=numAT; 14 else{ // if('P'==strPAT[istr]) 15 num+=numPAT; 16 if(num>=1000000007) num%=1000000007; 17 } 18 } 19 20 printf("%d",num); 21 return 0; 22 }
第一次刷題時的代碼 3月19日 14:46
1 #include<stdio.h> 2 #include<string.h> 3 int main() 4 { 5 char str[100000]; 6 gets(str); 7 8 int istr=strlen(str); 9 long long numA=0,numT=0,numP=0; 10 while(istr>0) 11 { 12 istr--; 13 if('T'==str[istr]) numT++; 14 else if('A'==str[istr]) numA+=numT; 15 else numP+=numA; 16 } 17 18 printf("%lld",numP%1000000007); 19 return 0; 20 21 }