首页 > 试题广场 >

Count PAT's (25)

[编程题]Count PAT's (25)
  • 热度指数:2997 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 32M,其他语言64M
  • 算法知识视频讲解
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.

输入描述:
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.


输出描述:
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.
示例1

输入

APPAPT

输出

2
import java.util.Scanner;

public class Main {

    /**
     * @param args
     */
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        String PATStr = scanner.next();
        int countP = 0;
        int result = 0;
        int countT = 0;
        for (int i = 0; i < PATStr.length(); i++) {
            if (PATStr.charAt(i) == 'T') {
                countT++;
            }
        }
        for (int i = 0; i <PATStr.length(); i++) {
            if (PATStr.charAt(i) == 'P') {
                countP++;
            }
            if (PATStr.charAt(i) == 'T') {
                countT--;
            }
            if (PATStr.charAt(i)=='A') {
                result = (result+(countP*countT)%1000000007)%1000000007;
            }
        }
        System.out.println(result);
    }

}

发表于 2018-09-05 09:48:58 回复(0)
#include <iostream>
#include <string>
using namespace std;

#define MAX_SIZE 1000000007

int dpPAT;
int dpAT;
int dpT;

int main()
{
	string s; cin >> s; int n = s.size();
	dpT= s[n - 1] == 'T' ? 1 : 0; 
	dpAT = dpPAT = 0;
	for (int i = n - 1; i > 0; --i) {
		dpT = s[i - 1] == 'T' ? 1 + dpT : dpT;
		dpAT = s[i - 1] == 'A' ? dpT + dpAT : dpAT;
		dpAT %= MAX_SIZE;
		dpPAT= s[i - 1] == 'P' ? dpAT + dpPAT : dpPAT;
		dpPAT %= MAX_SIZE;
	}
	cout << dpPAT;
	return 0;
}


发表于 2020-12-03 09:40:58 回复(0)
/*
    *记录P的前缀和和T的后缀和,遍历A统计前后P和T的数量,相乘加和即可
*/
#include <bits/stdc++.h>
(755)#define LL long long 
using namespace std;
const int AX = 1e5 + 666 ; 
const LL MOD = 1e9 + 7 ; 
LL p[AX]; 
LL t[AX]; 
int main(){
	string s ;
	cin >> s ; 
	long long res = 0 ; 
	int len = s.size() ; 
	for( int i = 0 ; i < len ; i++ ){
		if( !i ) p[i] = ( s[i] == 'P' ) ;
		if( i ) p[i] = p[i-1] + ( s[i] == 'P' ) ;
	}
	t[len] = 0 ; 
	for( int i = len - 1 ; i >= 0 ; i-- ){
		t[i] = t[i+1] + ( s[i] == 'T' ) ;
	}
	for( int i = 1 ; i < len - 1 ; i++ ){
		if( s[i] == 'A' ) res = ( res + 1LL * p[i-1] * t[i+1] ) % MOD ; 
	}
	cout << res ;
	return 0 ;
}

发表于 2020-02-28 10:41:23 回复(0)
啥头像
#include <iostream>
#include <string>
#include <stdio.h>

using namespace std;

int main()
{
    string str; cin >> str;
    int p=0, pa=0, pat=0, len = str.length();
    for(int i=0; i<len; i++) {
        if(str[i] == 'P') {
            p++;
        } else if(str[i] == 'A') {
            pa += p; pa %= 1000000007;
        } else {
            pat += pa; pat %= 1000000007;
        }
    }
    printf("%d", pat);
    return 0;
}


发表于 2015-12-28 08:37:15 回复(3)
//学习了一下大佬的思路
/*p=2;       APPAPATT
pa=0+p=2;
p=3;
pa=2+3=5;
t=0+pa=5;
t=t+pa=10
*/
#include<iostream>
(720)#include<vector>
#include<string>
using namespace std;
int main(){
    int p=0,pa=0,pat=0;
    string s;
    cin>>s;
    for(int i=0;i<s.size();i++){
        if(s[i]=='P') p++;
        else if(s[i]=='A') pa=pa+p;
        else{pat=pat+pa;pat%=1000000007;}
    }
    printf("%d",pat);
}


发表于 2020-03-21 12:35:38 回复(0)
#include <iostream>
using namespace std;

int main()
{
    int p = 0, pa = 0, pat = 0;
    char c;
    while(cin >> c){
        if(c == 'P') {
            p++;
            p %= 1000000007;
        }
        else if (c == 'A'){
            pa += p;
            pa %=1000000007;
        }
        else if(c=='T'){
            pat += pa;
            pat %= 1000000007;
        }
    }
    cout << pat << endl;
    return 0;
}


发表于 2019-08-26 16:25:50 回复(0)

#include<iostream>
#include<stdio.h>
#include<vector>
#include<string>
using namespace std;
const int maxn = 100009;
const int mod = 1000000007;

struct Node{    //message of char 'A'
    int lp;    //number of 'P' in left 
    int rt;    //number of 'T' in right
}nodea[maxn];

int ans;
int main(){
    //receive input data
    string input;
    int tlp=0,trt = 0;
    cin >> input;
    //recorde lp of each char 'A';
    for (int i = 0; i < input.length(); i++){
        if (input[i] == 'P') tlp++;
        else if (input[i] == 'A') nodea[i].lp = tlp;
    }
    //recorde rt of each char 'A'
    for (int i = input.length() - 1; i >= 0; i--){
        if (input[i] == 'T') trt++;
        else if (input[i] == 'A')nodea[i].rt = trt;
    }
    //caculate the answer
    for (int i = 0; i < maxn; i++){
        int add = nodea[i].lp*nodea[i].rt;
        if (add!=0){
            ans += add;
            ans %= mod;
        }
    }
    cout << ans << endl;
}






编辑于 2019-04-09 12:17:16 回复(0)
 
#include <bits/stdc++.h>
using namespace std;
const int maxn = 1e5+5;
const int mod = 1e9+7;
int dp[maxn][3];  // 0 P  1 A  2 T
int main() {
    std::ios::sync_with_stdio(false);
    string s;
    cin >> s;
    if (s[0] == 'P')
        dp[0][0]++;
    for (int i = 1; i < s.size(); ++i) {
        dp[i][0] = dp[i-1][0];
        if (s[i] == 'P')
            dp[i][0]++;
        dp[i][0] %= mod;
        dp[i][1] = dp[i-1][1];
        if (s[i] == 'A')
            dp[i][1] += dp[i-1][0];
        dp[i][1] %= mod;
        dp[i][2] = dp[i-1][2];
        if (s[i] == 'T')
            dp[i][2] += dp[i-1][1];
        dp[i][2] %= mod;
    }
    cout << dp[s.size()-1][2] << endl;
    return 0;
}


发表于 2019-02-02 11:31:01 回复(0)
con1,con2,con3 = 0,0,0
n = input()
for i in n:
    if i=='P':
        con1+=1
    if i=='A':
        con2+=con1
    if i=='T':
        con3+=con2
print(con3%1000000007)
这和爬楼梯的问题很像
发表于 2018-12-07 20:49:43 回复(0)
//思路:枚举每个A,前面出现了多少次P,后面出现了多少T;(前缀和)
//注意理解代码注释处为什么是错的。
#include <bits/stdc++.h>
using namespace std;
const int maxn=1e5+5,mod=1e9+7;
char A[maxn];
int sum_p[maxn],sum_t[maxn],ans;
int main(){
    scanf("%s",A+1);int len=strlen(A+1);
    for(int i=1;i<=len;++i)
        sum_p[i]+=sum_p[i-1]+(A[i]=='P'?1:0);  
    for(int i=len;i>=1;--i)
        sum_t[i]+=sum_t[i+1]+(A[i]=='T'?1:0);
    for(int i=1;i<=len;++i)
        if(A[i]=='A')  ans=(sum_p[i-1]%mod*sum_t[i+1]%mod+ans)%mod;//ans+=sum_p[i-1]*sum_t[i+1]%mod;
    printf("%d\n",ans);
    return 0;
}

发表于 2018-03-10 00:38:26 回复(0)
题意:统计一个字符串序列中出现的PAT的个数,它是这样算的,只要是PAT这样的顺序,不管中间空有多少格,都算一个。
思路:打表,即可以先从右到左遍历一遍,统计当前位置i,右边出现的T字符个数,然后从做到右遍历,统计出当前位置j的左边P字符个数,若j处是A,则计数PAT的个数

#include <cmath>
#include <iostream>
#include <cstdio>
#include <vector>
#include <algorithm>
using namespace std;

string list;         //字符串序列
vector<int> numT;    //计数i位置,后面出现的T字符数

int main() 
{     
freopen("C:\\Documents and Settings\\Administrator\\桌面\\data.txt", "r", stdin);
cin >> list;
numT.resize(list.length());   //将numT重置为与字符串序列相同长度

int cntT = 0;
numT[list.length() - 1] = 0;  //置最后一个为0
for (int i = list.length() - 1; i > 0; i--)   //从后往前遍历
{
if (list[i] == 'T')
cntT++;
numT[i - 1] = cntT;     //numT[i]表示从list[i + 1]至list[list.size() - 1]中出现的T个数
}
int cntP = 0;
int cntPAT = 0;   //结果
for (int i = 0; i < list.size(); i++)  //从前往后遍历
{
if (list[i] == 'P')    //当前字符为P,更新cntP
cntP++;
else if (list[i] == 'A')   //为A,更新cntPAT
{
cntPAT = (cntPAT + cntP * numT[i]) % 1000000007;
}
}
cout << cntPAT << endl;
while (1);
return 0;
}


发表于 2017-09-04 20:36:05 回复(0)
看了下其实其他的解题报告里的效率更高 可以看作这个思路的优化版
不过这个思路比较容易懂 可以先看懂这个再去那个
思路比较清晰代码也比较短不讲了,直接看代码就好
#include <iostream>
#include <vector>
using namespace std;

int main(int argc, const char* argv[]) {
	ios::sync_with_stdio(false);
	int P = 0, Count = 0;
	vector<int> A;
	char read;
	while ((read = cin.get()) - '\n') {
		if (read == 'P') P++;
		if (read == 'A') A.push_back(P);
		if (read == 'T') {
			for (int i = 0;i < A.size();i++) Count += A[i];
			Count %= 1000000007;
		}
	}
	cout << Count;
	return 0;
}

编辑于 2017-03-03 14:55:55 回复(0)
#include<cstdio>
using namespace std;

const int MAX_BUFFER = 100005;
char str[MAX_BUFFER];
int p = 0,pa = 0,pat = 0;

int main(){
	scanf("%s",str);
	int i = 0;
	char curr;
	while( (curr = str[i++]) != '\0'){
		switch(curr){
			case 'P':
				p++;
				p %= 1000000007;
				break;
			case 'A':
				pa += p;
				pa %= 1000000007;
				break;
			case 'T':
				pat += pa;
				pat %= 1000000007;
				break;
		}
	}
	printf("%d",pat);
		
	return 0;
}

发表于 2017-01-24 20:54:24 回复(1)
来自鄙人博客http://blog.csdn.net/sinat_29278271,还有其他一些有意思的题目的题解,欢迎前去吐槽纠错
    从前看过一道题目,让你数一个序列中有几个ACM,要不这道题目还真的不能太愉快地解决,策略是对于每个A统计A左边P的个数,A右边T的个数,可以通过将P和T的个数处理成前缀和来解决。直接上代码
# include <cstdio>
# include <iostream>
# include <cstring>
# include <cstdlib>
# include <stack>
# include <queue>
using namespace std;

# define moder (1000000007)

char str[100050];
int main()
{
    int p[100050],t[100050];
    scanf("%s",str);
    int Lenth = strlen(str);
    int i;
    for (i=0;i<Lenth;i++)
        {
            if (i==0)
                p[i] = 0;
            else
                p[i] = p[i-1];
            if (str[i]=='P')
                p[i]++;
        }
    for (i=Lenth-1;i>=0;i--)
        {
            if (i==Lenth-1)
                t[i] = 0;
            else
                t[i] = t[i+1];
            if (str[i]=='T')
                t[i]++;
        }
    int ans = 0;
    for (i=0;i<Lenth;i++)
        {
            if (str[i]=='A')
                ans = ( ( p[i] * t[i] ) % moder + ans ) % moder;
        }
    printf("%d\n",ans);
    return 0;
}

发表于 2015-08-30 02:07:43 回复(0)
#include <iostream>
using namespace std;
void countofpat(char *a,int n,int &count)
{
 int countp = 0,counta = 0,countt = 0;
 int i,j,k;
 for(i = 0; i < n;i++)
 {
  if(a[i] == 'p')
  {
   countp++;
  }
  else
  {
   if(countp>0)
   {
    for(j = i; j <= n-1;j++)
    {
     if(a[j] == 'a')
     {
      counta++;
     }
     else
     {
      if(counta>0)
      {
       for(k = j ; k < n;k++)
       {
        if(a[k] == 't')
         countt++;
       }
       count+=(countp*counta*countt);      
       countt = 0;
      }
       counta = 0;
     }
    }
    
   }
  countp = 0;
  } 
 }
}
int main()
{
   char *a = "appapat";
   int len = strlen(a);
   int count = 0;
   countofpat(a,len,count);
   cout<<count;
 return 0;
}
发表于 2015-06-04 19:47:46 回复(0)
js:
    
var str ="APPAPT";
 
for(var n =0,l = str.split(/P/g).length;--l;){
  var a = str = str.substring(str.indexOf("P")+1);
  for(var i = str.split(/A/g).length;--i;){
    a = a.substring(a.indexOf("A")+1);
    n += a.split("T").length -1;
  }
}
 
alert(n);
编辑于 2015-06-02 22:34:55 回复(0)
我想问问,(在了解网上其他人更优质的解法之前)这道题,我是这么解的,
但依然无法通过PAT主站部分示例,以及牛客网所有示例。
我的问题到底出在哪呢~
1.先寻找第一个出现的A,再计算A左边P的个数,A右边T的个数。countP*countT累加进sum值
2.上一个A置成其他无影响字符"#",再重复第一步。
3. 最后没有A的时候跳出循环,输出sum。
代码如下:
#include <iostream>
#include <string>
#include <cstdlib>
#include <algorithm>
using namespace std;

int main() {
    string line;
    cin >> line;
    string::iterator indexA , lastIndexA;
    int countP = 0,  sum = 0;
    indexA = find(line.begin(), line.end(), 'A');
    lastIndexA = line.begin();
    int countT = count(line.begin(), line.end(), 'T') ;
    while(indexA != line.end())
    {
        countP += count(lastIndexA, indexA, 'P');
        countT -= count(lastIndexA, indexA, 'T');
        sum += countP*countT;
        *indexA = '#';
        lastIndexA = indexA;
        indexA = find(indexA+1, line.end(), 'A');
    }

    cout << (sum%1000000007) << endl;
    return 0;
}
[已解决]:原因:int 越界。
编辑于 2015-05-27 18:37:05 回复(2)