运行要求
运行时间限制: 2sec
内存限制: 1024MB
原题链接

题目
由字母‘R’‘G’‘B’构成的长度为N的字符串S。
字符串中存在组合
求字符串中满足以下条件的组合的个数

  • 条件1: Si != Sj, Sj!= Sk, Si != Sk
  • 条件2: j-i != k - j

输入前提条件

  • 1<=N<=4000
  • 字符串仅有‘R’,‘G’,‘B’构成,字符串的长度为N

输入
输入都以以下标准从命令行输入

N
S

输出

输出满足条件的组合的数量

例1
输入

4
RRGB

输出

1

只有(1,3,4)的组合满足题目所要求的两个条件。(2,3,4)的组合虽然满足题目的条件1,但是不满足条件2

例2
输入

39
RBRBGRBGGBBRRGBBRRRBGGBRBGBRBGBRBBBGBBB

输出

1800

读懂题目
这道题的意思就是说
我们要在一长串字符串中找3个字符
3个字符是自左到右可能有下面6种情况
RGB
RBG
GRB
GBR
BGR
BRG
然后每个字符之间的距离要不一样
也就是说
BXXXRXXXG是可以的
BXRXG,BXXRXG是不可以的
X为‘R’或‘G’或‘B’
名称未設定.001.jpeg

解题思路
1. 1<=N<=4000,也就是说嵌套一层For循环O(N2)的复杂度是可以满足时间要求的

2. 正向思维求解,肯定是太复杂的,比如S=‘RGGGBBRG’我们要分别考虑第一个点是'R','G','G','G','B','B','R','G'的情况,然后考虑子情况。。。。。

3. 反向思维求解,先找出所有的情况,然后再减去不符合要求的情况

4. 所有的情况求解
因为要在字符串中各找出一个'R',一个'G',一个'B'。所以就是在R,G,B的区间中分别选择一个元素。
所以总共的数量是R的数量G的数量B的数量
名称未設定.gif

5. 不符合要求的情况
不符合要求的情况要满足两个条件
i,j的步长和j,k的步长一样
i,j,k没有重复的

遍历找步长一样所有组合,顺便看看组合的3个元素有没有重复的
长度为N的字符串中取3个元素的话,最小的步长为1,最大的为Math.ceil(N/2)
所以按照以下嵌套循环的方式可以求出的

名称未設定2.gif

代码

import math
N = int(input())
S = input()

def calculate(n, s):
    arr = list(s)

    rNum = arr.count("R")
    gNum = arr.count("G")
    bNum = arr.count("B")

    sum = 0

    for step in range(1,math.ceil(n / 2) + 1):
        for i in range(n - 2*step):
            s = "".join([arr[i],arr[i+step],arr[i+step*2]])
            if s == "RGB" or s == "RBG" or s == "BGR" or s == "BRG" or s == "GBR" or s == "GRB":
                sum = sum + 1


    print(rNum*gNum*bNum - sum)



calculate(N, S)

总结

本题考察的是一个反向求解的思维
另外还考察了对排列组合的理解和对复杂度的理解

※ 另外,我会在我的微信个人订阅号上推出一些文章,欢迎关注
二维码.jpg



伟大不DIAO
1 声望1 粉丝

Done is better than perfect