1040 有几个PAT (25 分)
题目链接:1040 有几个PAT (25 分)
做这道题目,遇到了新的困难。解决之后有了新的收获,甚是欣喜!
刚开始我用三个vector数组存储P A T三个字符出现的位置,然后三层for循环,根据字符次序关系,
统计PAT出现的次数。这样提交后三个测试点超时。代码如下:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include <bits/stdc++.h> 2 using namespace std; 3 4 int num=1000000007; 5 char str[100001]; 6 7 vector<int> p; 8 vector<int> a; 9 vector<int> t; 10 int main() 11 { 12 scanf("%s",str); //输入指定字符串 13 int count=0; 14 for(int i=0;i<strlen(str);i++) 15 { 16 if(str[i]=='P') 17 p.push_back(i); 18 else if(str[i]=='A') 19 a.push_back(i); 20 else 21 t.push_back(i); 22 } 23 for(int i=0;i<p.size();i++) 24 { 25 for(int j=0;j<a.size();j++) 26 { 27 for(int k=0;k<t.size();k++) 28 { 29 if(p[i]<a[j]&&a[j]<t[k]) 30 count++; 31 } 32 } 33 } 34 printf("%d",count%num); 35 return 0; 36 }
后来改进为两层for循环,依旧超时!冥思苦想不得其解,不得已求助网上大神。
具体思想:要想知道构成多少个PAT,那么遍历字符串后对于每一个A,它前面的P的个数和它后面的
T的个数的乘积就是能构成PAT的个数。然后依次累加每个A的结果即可。
统计当前字符A的前面的P的个数简单容易
那么怎么统计当前字符A的后面的T的个数呢?
可以先遍历整个字符串统计整个字符串中T的个数。可以再下一次遍历时,遇到一个T就做一次自减操作,
这样就可以得到当前字符A的后面的T的个数。
整个算法伪代码如下
先遍历整个字符串,统计T的个数countT
遍历整个字符串
若遇到P,当前字符前的P的个数++,countP++
若遇到T,countT--,表示当前字符A后的T的个数
若遇到字符A,统计当前字符A可以构成多少个PAT,即countP*countT,然后累加每次A的结果。
1 #include <bits/stdc++.h> 2 using namespace std; 3 4 char str[100001]; 5 6 int main() 7 { 8 scanf("%s",str); 9 int ans=0; 10 int countP,countT; 11 countP=countT=0; 12 //先统计整个字符串中T的个数即countT 13 for(int i=0;i<strlen(str);i++) 14 { 15 if(str[i]=='T') 16 countT++; 17 } 18 for(int i=0;i<strlen(str);i++) 19 { 20 if(str[i]=='P') 21 countP++; 22 else if(str[i]=='T') 23 countT--;//总的T的个数减去待统计字符A的之前的T的个数,等于待统计A的之后的T的个数,秒! 24 else 25 ans=(ans+countP*countT)%1000000007; 26 } 27 printf("%d",ans); 28 return 0; 29 }