1040. 有几个PAT(25)

原题: 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()) != '\n') {
        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

posted @ 2017-11-12 22:06  阿胜4K  阅读(293)  评论(0编辑  收藏  举报