1093 Count PAT’s (25 分)
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
思路
这个题目的意思是让我们在一段长度不超过105只含有P、A、T三种字母的字符串序列中寻找顺序的PAT的个数,其中不要求PAT三个字母连续。
此题通过三重循环可以解出答案,但是由于运行限制时间为150ms,粗略计算时间复杂度约为O(n3),即大约需要计算1015次计算,而计算机一秒大约能执行5*108次计算,所以暴力算法肯定会超时。
于是试想能否用O(n)的复杂度的算法计算呢。
转换角度,PAT的个数等于A左边P的个数乘以A右边T的个数,于是可以用一个数组记录A第i位左边包括第i位上的P的个数。同样的方法用于查找T,从后往前查找T,在计算T的个数的同时,查找A,一旦找到A就开始累加该位左边P的总数与右边T的总数的乘积。
代码如下:
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.util.StringTokenizer;
public class Main{
static int ans=0;
static int[] leftP;
static int rightT=0;
static int MOD=1000000007;
static void search(String str){
int len=str.length();
for(int i=0;i<len;i++) {
if(i==0) {
if(str.charAt(i)=='P') leftP[i]=1;
}else {
if(str.charAt(i)=='P') {
leftP[i]=leftP[i-1]+1;
}
else {
leftP[i]=leftP[i-1];
}
}
}
for(int i=len-1;i>=0;i--) {
char ch=str.charAt(i);
if(ch=='T') {
rightT++;
}
if(ch=='A') {
ans=(ans+leftP[i]*rightT)%MOD;
}
}
System.out.println(ans);
}
public static void main(String[] args) throws IOException {
// TODO Auto-generated method stub
//Scanner sc=new Scanner(System.in);
BufferedReader reader=new BufferedReader(new
InputStreamReader(System.in));
StringTokenizer strtoken= new StringTokenizer(reader.readLine());
String str=strtoken.nextToken();
leftP=new int[100010];
for(int i=0;i<str.length();i++) {
leftP[i]=0;
}
search(str);
}
}
结果![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/a6ea4f859319c4ab6c9221131730b425.png)
很开心看到ac后耗时并不多,这里采用的是BufferReader进行读入,使用Scanner真的很耗时,耗到不能通过…