原题: https://www.patest.cn/contests/pat-b-practise/1040
思路: 先给大家扔个测试PAPAATTPATTT
, 人工查一下这段字符串能组成
34个PAT
.
这一题我自己的想法非常的渣, 也非常复杂, 最后看了OliverLew大神的解答,
才明白这题原来是这样搞的. 本题的解法非常类似"在线处理"的思想.
观察下面3段字符串
- PA (只能组成1个PA)
- PAPA (第一个A能组成1个PA, 第2个A能组成2个PA, 一共1+2=3个PA)
- PAPAPA (1 + 2 + 3 = 6个PA)
现在我们看一下PAPAATTPATTT
这个字符串, 我们不要一开始就盯着PAT
这
3个字符, 而是先看字符串里有多少P, 再看有多少PA, 最后确定有多少PAT.
从左到右一个一个字符的看, 下面我给字符串标上号
PAPAATTPAT T T
0123456789 10 11 - 走到下标0, P=1, PA=0, PAT=0
- 走到下标1, P=1, PA=1, PAT=0
- 走到下标2, P=2, PA=1, PAT=0
- 走到下标3, P=2, PA=1+2=3, PAT=0
- 走到下标4, P=2, PA=3+2=5, PAT=0
- 走到下标5, P=2, PA=5, PAT=5
- 走到下标6, P=2, PA=5, PAT=5+5=10
- 走到下标7, P=3, PA=5, PAT=10
- 走到下标8, P=3, PA=5+3=8, PAT=10
- 走到下标9, P=3, PA=8, PAT=10+8=18
- 走到下标10, P=3, PA=8, PAT=18+8=24
- 走到下标0, P=3, PA=8, PAT=24+8=34
相信大家已经看明白, 是的就这么简单, 寥寥10几行搞定, 我一开始自己搞了
6个多小时, 代码一百多行, 还是不能全对, 思想太重要了.
注意取余数是在中间过程就取, 不用等到最后总数再取余.
完整实现:
#include <stdio.h>
#define MOD 1000000007
int main (void) {
long int p = 0;
long int pa = 0;
long int pat = 0;
char ch;
while ((ch = getchar()) != '
') {
if (ch == 'P') p++;
if (ch == 'A') pa = (pa + p) % MOD;
if (ch == 'T') pat = (pat + pa) % MOD;
}
printf("%ld", pat);
return 0;
}
参考资料:
OliverLew的简书: http://www.jianshu.com/p/65291de1906b