PAT乙级1021-1040
乙级的题目就是简单啊……一会会就一道……
1021 个位数统计
in_str = input()
output = [0] * 10
for c in in_str:
output[int(c)] = output[int(c)] + 1
for i in range(0,10):
if output[i] != 0:
print("{}:{}".format(i,output[i]))
1022 D进制的A+B
A,B,radix = [int(x) for x in input().split(' ')]
C = A + B
outstr = ""
if C == 0 :
print(C)
else:
while(C != 0):
C,r = divmod(C,radix)
outstr = str(r) + outstr
print(outstr)
1023 组个最小数
line = [int(x) for x in input().split(' ')]
numlist = []
min = 10
for i in range(0,10):
if line[i] != 0 and i != 0 and i < min:
min = i
numlist += [i] * line[i]
numlist.sort()
numlist.remove(min)
print(min,end="")
for x in numlist:
print(x,end="")
1024 科学计数法
line = input()
if line[0] == '+':
fuhao = ''
else: fuhao = '-'
line = line[1:]
Epos = line.index('E')
Enum = int(line[Epos + 1:])
num = line[0:Epos]
num = num[0:1] + num[2:] #移除.号
if Enum < 0:
num = "0" * (-1 * Enum) + num
num = num[0:1] + '.' + num[1:]
elif Enum >= 0:
if len(num) - 1 <= Enum:
num = num + "0" * ( Enum - len(num) + 1 )
else:
new_comma_pos = Enum + 1
num = num[0:new_comma_pos] + '.' + num[new_comma_pos:]
print(fuhao,end = "")
print(num)
1025 翻转链表
正确但超时的算法
//最简单的方法是直接用一个维度100000的数组,直接保存输入,之后再做输出。
//用map也不是不可以,就是更繁琐一点吧。虽然算法无误,但是节点5超时了。
#include<iostream>
#include<vector>
#include<string>
#include<algorithm>
using namespace std;
struct node{
string ptr;
int data;
string next_ptr;
node() = default;
node(const string &a,const int b,const string &c):ptr(a),data(b),next_ptr(c){}
};
int main(){
ios::sync_with_stdio(false);
int origin_head, nodes_num, K;
cin >> origin_head >> nodes_num >> K;
vector<node> all_nodes(100000);
for(int i = 0 ; i != nodes_num ; ++i){
string a,c;
int b;
cin >> a >> b >> c;
all_nodes[stoi(a)] = node(a,b,c);
}
vector<node> link; //模拟一个链表
int tmp1 = origin_head;
do{
link.push_back(all_nodes[tmp1]);
tmp1 = stoi(all_nodes[tmp1].next_ptr);
}while(tmp1 != -1);
nodes_num = link.size(); //有些节点可能是废节点,不入link
//此时可以开始翻转了,当然是要用算法库了
int reverse_from = 0;
while(reverse_from + K <= nodes_num){
reverse(link.begin() + reverse_from , link.begin() + reverse_from + K);
reverse_from += K;
}
//排完序了,开始输出,这里的正常思路是先把链表建立起来,nextptr都刷对以后再来输出
//但也可以一次读两个,来偷懒
for (int i = 0 ; i != nodes_num - 1 ; ++i){
string next_ptr = link[i+1].ptr;
cout << link[i].ptr << " " << link[i].data << " " << next_ptr << endl;
}
cout << link.back().ptr << " " << link.back().data << " -1" << endl;
return 0;
}
正确且未超时的算法
//最简单的方法是直接用一个维度100000的数组,直接保存输入,之后再做输出。
//用map也不是不可以,就是更繁琐一点吧。
#include <algorithm>
#include <string>
#include <vector>
#include <cstdio>
//#include<iomanip>
using namespace std;
struct node {
int ptr;
int data;
int next_ptr;
node() = default;
node(const int &a, const int &b, const int &c)
: ptr(a), data(b), next_ptr(c) {}
};
int main() {
ios::sync_with_stdio(false);
int origin_head, nodes_num, K;
scanf("%d %d %d",&origin_head, &nodes_num, &K);
vector<node> all_nodes(100000);
for (int i = 0; i != nodes_num; ++i) {
int a, b, c;
scanf("%d %d %d",&a, &b, &c);
all_nodes[a] = node(a, b, c);
}
vector<node> link; //模拟一个链表
int tmp1 = origin_head;
do {
link.push_back(all_nodes[tmp1]);
tmp1 = all_nodes[tmp1].next_ptr;
} while (tmp1 != -1);
nodes_num = link.size(); //有些节点可能是废节点,不入link
//此时可以开始翻转了,当然是要用算法库了
int reverse_from = 0;
while (reverse_from + K <= nodes_num) {
reverse(link.begin() + reverse_from, link.begin() + reverse_from + K);
reverse_from += K;
}
//排完序了,开始输出,这里的正常思路是先把链表建立起来,nextptr都刷对以后再来输出
//但也可以一次读两个,来偷懒
for (int i = 0; i != nodes_num - 1; ++i) {
int ptr;
int next_ptr;
ptr = link[i].ptr;
next_ptr = link[i+1].ptr;
printf("%05d %d %05d\n",ptr,link[i].data,next_ptr);
//cout<<setw(5)<<setfill('0')<<ptr<<" "<<link[i].data<<" "<<setw(5)<<setfill('0')<<nextptr<<endl;
}
printf("%05d %d -1\n",link.back().ptr,link.back().data);
//cout<<setw(5)<<setfill('0')<<link.back().ptr<<" "<<link.back().data<<" -1"<<endl;
//在所有其他地方都一样的情况下,只是修改printf为cout,节点5就超时了,而printf在节点5的运行时间只有106ms
//可见cout相比printf的巨大效率差,要知道这道题的超时是300ms,也就是说cout的效率低了3倍不止
return 0;
}
关于超时的一点想法
对于在CPP代码里使用scanf和printf,其实我是拒绝的,但是架不住数据稍大时巨大的效率差,这个效率差我们已经在之前的某一次例题中讲解过了,大概scanf是cin的4倍,这道题告诉我们,printf的效率也是cout的4倍(也可能是因为用了iomanip库反复设置格式的原因,但总之效率不咋地是没跑了)。我用这道题又做了一次测试。
当使用iostream库,关闭stdin同步,用cin输入,printf输出时,节点5的时间是107ms,使用scanf输入,printf输出时,节点5的时间是106ms,可见关闭了stdin同步的cin效率与scanf相差无几。
1016 程序运行时间
CLK_TIK = 100
begin,end = input().split(' ')
ticks = int(end) - int(begin)
seconds = int(ticks/CLK_TIK) #这里不能用round,原因见下
if ticks % CLK_TIK >= 50:
seconds += 1
hh = int(seconds / 3600)
seconds -= 3600 * hh
mm = int( seconds / 60)
seconds -= 60 * mm
ss = seconds
hh = str(hh) if hh > 10 else '0' + str(hh)
mm = str(mm) if mm > 10 else '0' + str(mm)
ss = str(ss) if ss > 10 else '0' + str(ss)
print(hh+":"+mm+":"+ss)
python的round函数
不啰嗦,直接上图:

可见当小数位刚好为0.5时,会向偶数取整,而不是四舍五入。
1027 打印沙漏
num,c = input().split()
num = int(num)
if num < 7: #只够输出一行
print(c)
print(num - 1)
else:
max_line = 3 #一行最多输出几个字符,从3起算
used = 1
while used + max_line * 2 <= num:
used += max_line * 2
max_line += 2
max_line -= 2 #前面加多了……
tmp = max_line
blanknum = 0
while tmp != 1:
print(" " * blanknum + c * tmp)
blanknum += 1
tmp -= 2
while tmp <= max_line:
print(" " * blanknum + c * tmp)
blanknum -= 1
tmp += 2
print(num - used)
1028 人口普查
#include <stdio.h>
#include <string.h>
int isolder(int ayy, int amm, int add, int byy, int bmm, int bdd) {
if (ayy < byy || (ayy == byy && amm < bmm) ||
(ayy == byy && amm == bmm && add < bdd))
return 1;
else
return 0;
}
int isyounger(int ayy, int amm, int add, int byy, int bmm, int bdd) {
return isolder(byy, bmm, bdd, ayy, amm, add);
}
int birthday_ok(int a, int b, int c) {
if (a < 1814 || (a == 1814 && b < 9) || (a == 1814 && b == 9 && c < 6))
return 0;
if (a > 2014 || (a == 2014 && b > 9) || (a == 2014 && b == 9 && c > 6))
return 0;
return 1;
}
int main() {
char oldest[6], youngest[6], now[6];
int oldyy = 2018, oldmm = 7, olddd = 13;
int youngyy = 1800, youngmm = 7, youngdd = 13;
int nums, legal = 0;
scanf("%d", &nums);
for (int i = 0; i != nums; ++i) {
int nowyy, nowmm, nowdd;
scanf("%s %d/%d/%d", now, &nowyy, &nowmm, &nowdd);
if (birthday_ok(nowyy, nowmm, nowdd)) {
legal++;
if (isolder(nowyy, nowmm, nowdd, oldyy, oldmm, olddd)) {
strcpy(oldest,now);
oldyy = nowyy;
oldmm = nowmm;
olddd = nowdd;
}
if (isyounger(nowyy, nowmm, nowdd, youngyy, youngmm, youngdd)) {
strcpy(youngest,now);
youngyy = nowyy;
youngmm = nowmm;
youngdd = nowdd;
}
}
}
if (legal != 0) //否则某节点会格式错误
printf("%d %s %s",legal,oldest,youngest);
else
printf("0");
return 0;
}
1029 坏键盘
#include <algorithm>
#include <iostream>
#include <string>
using namespace std;
int main() {
string a, b;
cin >> a >> b;
transform(a.begin(), a.end(), a.begin(), ::toupper);
transform(b.begin(), b.end(), b.begin(), ::toupper);
string output;
for (auto c : a) {
if (b.find(c) == string::npos && output.find(c) == string::npos){
output += c;
}
}
cout << output << endl;
return 0;
}
1030 完美数列
//本来,看到这道题可能隐含一个大数相乘的坑,当时我就想用python
//想不到,完全相同的逻辑,用python竟然会300ms超时……而用c++只用了37ms……
#include<cstdio>
#include<vector>
#include<algorithm>
#include<limits>
#define INT_MAX numeric_limits<int>::max()
using namespace std;
int main(){
int N,p;
scanf("%d %d",&N,&p);
vector<int> list(N);
for(int i = 0 ; i != N ; ++i)
scanf("%d",&list[i]);
sort(list.begin(),list.end());
int last = 0;
int maxlen = 0;
for (int i = 0 ; i != N ; ++i ){
int j;
if (INT_MAX / list[i] < p){ //可能出现大数相乘,超过int界限,因此这里用除法做个判断
maxlen = N - i;
break;
}
for (j = last ; j != N ; ++j){
if (list[j] > list[i] * p ){
last = j - 1;
break;
}
//程序如果到了这里退出循环,说明最后一个数都小
last = j;
}
if (last - i + 1 > maxlen)
maxlen = last - i + 1;
if (last == N - 1) //进一步优化速度,当last已经到最后一位时,就没有继续的必要了
break;
}
printf("%d\n",maxlen);
return 0;
}
1031 查验身份证
def is_not_ok(c):
quan = [7,9,10,5,8,4,2,1,6,3,7,9,10,5,8,4,2]
map = [1,0,10,9,8,7,6,5,4,3,2]
head = c[:17]
tail = int(c[17]) if c[17].isdigit() else 10
if head.isdigit() != True:
return True;
res = 0
for i in range(0,17):
res += int(head[i]) * quan[i]
res = map[res%11]
if res == int(tail):
return False
else: return True
def main():
N = int(input())
output = []
for i in range(0,N):
c = input();
if is_not_ok(c):
output.append(c)
if len(output) == 0:
print("All passed")
else:
for c in output:
print(c)
if __name__=="__main__":
main()
1032 挖掘机技术哪家强
#include<map>
#include<iostream>
using namespace std;
int main(){
ios::sync_with_stdio(false);
int N;
cin >> N;
map<int,int> score_sum;
int max_snum = -1 ,max_score = 0;
for(int i = 0 ; i != N ; ++i){
int snum,score;
cin >> snum >> score;
score_sum[snum] += score;
if (score_sum[snum] > max_score){
max_score = score_sum[snum];
max_snum = snum;
}
}
cout << max_snum << " " << max_score << endl;
return 0;
}
1033 旧键盘打字
超时解法
//第二行直接用getchar好了
//超时原因待排查,初步估计不是cin的锅,而是string的find函数比较低效
//果然不是cin的锅,看来得上set了
#include <iostream>
#include <string>
using namespace std;
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
string broken;
cin >> broken;
cin.get(); //跳过换行符
bool CAP_broken = false;
if (broken.find('+') != string::npos) {
CAP_broken = true;
}
char c;
while ((c = cin.get()) != '\n') {
if (isupper(c) && CAP_broken) {
; //啥都不做
} else {
if (broken.find(toupper(c)) == string::npos) {
cout << c;
}
}
}
}
不超时解法
//第二行直接用getchar好了
//超时原因待排查,初步估计不是cin的锅,而是string的find函数比较低效
//果然不是cin的锅,看来得上set了
#include <iostream>
#include <set>
using namespace std;
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
char c;
set<char> broken;
while((c = cin.get()) != '\n'){
broken.insert(c);
}
bool CAP_broken = false;
if (broken.find('+') != broken.end()) {
CAP_broken = true;
}
while ((c = cin.get()) != '\n') {
if (isupper(c) && CAP_broken) {
; //啥都不做
} else {
if (broken.find(toupper(c)) == broken.end()) {
cout << c;
}
}
}
}
时间对比


唔……只有节点3有区别,为毛啊?
1034 有理数四则运算
C++解法
#include<iostream>
#include<string>
using namespace std;
int zuidagongyueshu(long a, long b) {
int i = 0;
if (a == 0 || b == 0)
return 1;
/*for (i = min; ; --i) {//这样一个数一个数减下去,确实效率不高
if (!(a % i) && !(b % i))
break;
}*/
int c;
while (true) {
if ( ( c = a % b ) == 0)
return b;
else { a = b; b = c; }
}
return 1;
}
void getoper(long &up, long &down,string & ss){
if (up == 0 || down == 0) {
ss = '0';
return;
}
if (down < 0) {
down = 0 - down;
up = 0 - up;
}
int zuida = zuidagongyueshu(up, down);
if (zuida < 0) zuida = 0 - zuida;
up /= zuida; down /= zuida;
int int1 = up / down;
int up11 = up - down * int1;
if (int1 != 0) {
ss += std::to_string(int1) + " ";
}
if (int1 < 0) {
up11 = up11 >= 0 ? up11 : 0 - up11;
}
if (up11 != 0)
ss = ss + std::to_string(up11) + '/' + std::to_string(down);
else ss.pop_back();
if (int1 < 0 || up11 < 0)
ss = '(' + ss + ')';
}
int main() {
//坑在于,一个是虽然输入的数都是int,但是相乘后可能超出int,所以要用long
//另一个坑就要用整型最大值去测试了,很烦人的
//另一个坑是,我做了很多取负值的计算,假如值为Tmin,就出错
string a, b;
cin >> a >> b;
long up1 = std::stoi(a.substr(0, a.find('/'))), down1 = std::stoi(a.substr(a.find('/') + 1));
long up2 = std::stoi(b.substr(0, b.find('/'))), down2 = std::stoi(b.substr(b.find('/') + 1));
string oper1, oper2;
getoper(up1, down1,oper1);
getoper(up2, down2,oper2);
long result_up1 = up1 * down2 + up2 * down1, result_down1 = down1 * down2;
long result_up2 = up1 * down2 - up2 * down1, result_down2 = down1 * down2;
long result_up3 = up1 * up2 , result_down3 = down1 * down2;
long result_up4 = up1 * down2, result_down4 = up2 * down1;
string r1, r2, r3, r4;
getoper(result_up1, result_down1,r1);
getoper(result_up2, result_down2,r2);
getoper(result_up3, result_down3,r3);
if (oper2 == "0")
r4 = "Inf";
else getoper(result_up4, result_down4,r4);
cout << oper1 << " + " << oper2 << " = " << r1 << endl;
cout << oper1 << " - " << oper2 << " = " << r2 << endl;
cout << oper1 << " * " << oper2 << " = " << r3 << endl;
cout << oper1 << " / " << oper2 << " = " << r4 << endl;
return 0;
}
python解法
#fractions 模块有不少好用的功能,比如说gcd,求最大公约数的
#Fraction 会自动将分子分母最大公约掉
def get_str(a):
"""
将一个Fraction转换为一个字符串
"""
aup = a.numerator
adown = a.denominator
negative = False
if aup < 0:
negative = True
aup = -aup
if aup == 0:
ret = '0'
elif aup % adown == 0:
ret = str(int(aup / adown))
else:
int_part = int(aup / adown)
aup -= int_part * adown
if int_part == 0:
ret = str(aup) + '/' + str(adown)
else:
ret = str(int_part) + " " + str(aup) + '/' + str(adown)
if negative:
ret = "(-" + ret + ")"
return ret
def main():
from fractions import Fraction, gcd
a, b = input().split()
a = Fraction(a)
b = Fraction(b)
print("{} + {} = {}".format(get_str(a), get_str(b), get_str(a+b)))
print("{} - {} = {}".format(get_str(a), get_str(b), get_str(a-b)))
print("{} * {} = {}".format(get_str(a), get_str(b), get_str(a*b)))
if b != 0:
print("{} / {} = {}".format(get_str(a), get_str(b), get_str(a/b)))
else:
print("{} / {} = Inf".format(get_str(a), get_str(b)))
if __name__=="__main__":
main()
1035 插入与归并
//想不来怎么判断,不如直接实现插入和归并算法,一步一步求呗
#include <algorithm>
#include <iostream>
#include <vector>
using namespace std;
void insert(const vector<int> &origin, vector<int> &next_step, int sorted_num);
void merge(const vector<int> &origin, vector<int> &next_step, int length);
int main() {
ios::sync_with_stdio(false);
int N;
cin >> N;
vector<int> origin(N);
vector<int> half(N);
for (int i = 0; i != N; ++i) {
cin >> origin[i];
}
for (int i = 0; i != N; ++i) {
cin >> half[i];
}
vector<int> next_step;
for(int i = 0 ; i != N ; ++i){
insert(origin,next_step,i);
if (next_step == half){
cout << "Insertion Sort" << endl;
while(next_step == half) //这个while的意义下述
insert(origin,next_step,++i);
for(int j = 0 ; j != N - 1; ++j)
cout << next_step[j] << " ";
cout << next_step.back() << endl;
return 0;
}
}
next_step = origin;
int length = 2;
while(true){
merge(origin,next_step,length);
length *= 2;
if (next_step == half){
cout << "Merge Sort" << endl;
merge(origin,next_step,length);
for(int j = 0 ; j != N - 1; ++j)
cout << next_step[j] << " ";
cout << next_step.back() << endl;
return 0;
}
}
}
void insert(const vector<int> &origin, vector<int> &next_step, int index) {
int tmp = origin[index];
next_step.erase(next_step.begin() + index , next_step.end());
int size = next_step.size();
for (int i = 0; i != size; ++i) {
if (tmp < next_step[i]) {
next_step.insert(next_step.begin() + i, tmp);
break;
}
}
if (next_step.size() == size) { //并没有插入,说明tmp最大
next_step.push_back(tmp);
}
next_step.insert(next_step.end(),origin.begin() + index + 1 , origin.end());
}
void merge(const vector<int> &origin, vector<int> &next_step, int length) {
int i;
if (length >= origin.size()) {
sort(next_step.begin(), next_step.end());
} else {
for (i = 0; i <= origin.size() - length; i += length) {
sort(next_step.begin() + i, next_step.begin() + i + length);
}
if ( i != origin.size())
sort(next_step.begin() + i , next_step.end());
}
}
while循环的意义
有时候,插入算法在将一个新值纳入考虑时,并不会改变数列的顺序,比如
10
3 1 2 8 7 5 9 4 6 0
插入排序到第6个元素,"5"之后,得到以下数列:
1 2 3 5 7 8 9 4 6 0
当纳入第7个元素"9"之后,
数列是不变的,这就出问题了。
1036 跟奥巴马一起编程
#include<iostream>
using namespace std;
int main() {
int k;
char c;
cin >> k >> c;
for (int i = 0; i != (k+1)/2; ++i) {
for (int j = 0; j != k; ++j) {
if (i == 0 || i == (k - 1) / 2 || j == 0 || j == k - 1)
cout << c;
else cout << " ";
}
cout << endl;
}
return 0;
}
1037 在霍格沃兹找零钱
Price,Paid = input().split()
PG,PS,PK = [int(x) for x in Price.split('.')]
AG,AS,AK = [int(x) for x in Paid.split('.')]
PKS = PG * 29 * 17 + PS * 29 + PK
AKS = AG * 29 * 17 + AS * 29 + AK
back = AKS - PKS
if back < 0:
back = -back
negative = "-"
else:
negative = ""
backG = int(back / (29 * 17))
backS = int((back % (29 * 17)) / 29)
backK = back % 29
print(negative + str(backG) + '.' + str(backS) + '.' + str(backK));
1038 统计同成绩学生
#include<map>
#include<iostream>
using namespace std;
int main(){
ios::sync_with_stdio(false);
cin.tie(nullptr); //不加这句话,这种算法会超时
int s;
int N;
cin >> N;
map<int,int> scores;
for( int i = 0 ; i != N ; ++i){
cin >> s;
++scores[s];
}
cin >> N;
for(int i = 0 ; i != N - 1 ; ++i){
cin >> s;
cout << scores[s] << " ";
}
cin >> N;
cout << scores[N] << endl;
return 0;
}
再谈iostream的效率问题
为了下面说明的方便,我们在这里再推出一种算法:
#include<iostream>
#include<map>
#include<vector>
using namespace std;
int main() {
int k1;
int score;
int k2;
vector<int> results;
map<int, int> score_store;
cin >> k1;
while (k1--) {
cin >> score;
++score_store[score];
}
cin >> k2;
while (k2--) {
cin >> score;
results.push_back(score_store[score]);
}
for (auto it = results.begin(); it != results.end() - 1; ++it)
cout << *it << " ";
cout << results.back();
return 0;
}
与之前的算法基本相同,只是将结果收集到vector里,然后再输出。也就是说cin和cout不是像算法一里面那样交叉使用了,而是先cin完再cout。这就涉及到效率问题了。
ios::sync_with_stdio(false)的效率我们已经讨论过了,在算法二中,仅仅添加该语句,就将时间从125ms降到了54ms,不做详细讨论,在此只讨论cin.tie(nullptr)的问题。
在算法1中,没有cin.tie(nullptr),大节点直接超时(250ms),而加上的话只有56ms。在算法2中,没有的话大节点是54ms,有了是53ms,应该属于没有差异。
可见,在cin和cout交替调用的时候,cin.tie(nullptr)能带来很大的效率提升,但为什么cin要和cout绑定呢?
在《C++ Premiere 5th》P282中提到:
当一个输入流被关联到一个输出流时,任何试图从输入流读取数据的操作都会先刷新关联的输出流。标准库将cout与cin关联到一起,因此每次调用
cin>>val;都会导致cout的缓冲区被刷新。交互式系统通常应该关联输入流和输出流,这意味着所有输出,包括用户提示信息,都会在读操作之前被打印出来。
也就是说,关联这两个流之后,cin会不断刷新cout的缓冲区,也就是直接调用系统调用去实现IO操作了,交替使用当然效率惨不忍睹,但好处是这样不会导致输入输出混乱。否则下面的代码:
cin.tie(nullptr);
cout << "Input:";
cin >> val;
有可能在cout刷新缓存,Input:真正被写到控制台之前就提示输入了。但只是有可能,实际情况仍然取决于具体实现。
1039 到底买不买
//还以为是最长公共子序列,原来简单多了
//当然是换一家淘宝店买了
#include<iostream>
#include<map>
using namespace std;
int main(){
ios::sync_with_stdio(false);
char c;
map<char,int> get,want;
bool sufficient = true;
int gets = 0 , wants = 0;
while( (c = cin.get() ) != '\n'){
++get;
++gets;
}
while( (c = cin.get() ) != '\n'){
++want;
++wants;
}
int miss = 0;
for (auto it = want.begin() ; it != want.end() ; ++it){
if (get[it->first] < it->second){
sufficient = false;
miss += it->second - get[it->first];
}
}
if (sufficient){
cout << "Yes " << gets - wants << endl;
}else{
cout << "No " << miss << endl;
}
return 0;
}
1040 有几个PAT
//所以这道题想干嘛??
#include<stdio.h>
int main(){
long long Pnum = 0 , PAnum = 0 , total = 0;
char c;
while((c = getchar()) != '\n'){
switch(c){
case 'P':
++Pnum;
break;
case 'A':
PAnum += Pnum;
break;
case 'T':
total += PAnum;
total %= 1000000007;
}
}
printf("%d\n",total);
return 0;
}
0 条评论