Найти наибольшую подстроку, являющуюся радугой

Задачка с Т-Поколения После проливного дождя в Т-стране вышло солнце и небо окрасилось в три цвета: красный (R), зеленый (G), синий (B). Маленький мальчик Петя успел записать все цвета, которые он увидел, в одну строку s. Но вот незадача: ему стало интересно узнать размер самой большой радуги, которая была на небе, а считать он умеет только до двух. Радугой называется строка, имеющая вид R..RG..GB..B. Например, строка RRGGBB является радугой, а RGGBB и GGRRBB - нет. Помогите Пете! Найдите наибольшую подстроку строки, которую он записал, являющуюся радугой, и выведите её длину. Если ни одна подстрока не является радугой, выведите 0.

Формат входных данных:

В первой строке записано одно целое число n (1 6 n 6 105). Во второй строке записана строка s состоящая из n символов R, G, B.

Формат выходных данных:

Выведите одно число - длину наибольшей подстроки, являющейся радугой.

Входные данные:

7 RRRGGBB 6

8 RRGGGBBB 0

Языки: C++, Python, Java

Мои попытки:

Python:

Провален тест 2:

def find_rainbow(s):
    max_length = 0
    start = 0  # Позиция первого символа R
    for i in range(len(s)):
        if s[i] == 'R':
            start = i
            break
    end = len(s) - 1  # Позиция последнего символа B
    while start < end:
        g_pos = start + 1
        while g_pos < end and s[g_pos] != 'G':
            g_pos += 1
        b_pos = end - 1
        while b_pos >= g_pos and s[b_pos] != 'B':
            b_pos -= 1
        if g_pos > start and b_pos < end:  # Радуга найдена
            length = b_pos - start + 1
            if length > max_length:
                max_length = length
        start = g_pos + 1  # Переходим к следующей возможной радуге
    return max_length
n = int(input())
s = input()
result = find_rainbow(s)
print(result)

Провален тест 9:

input()
w=input().upper()
n=w.count('B')
t='R'*n+'G'*n+'B'*n
if t in w:
    print(3*n)
else:
    print(0)

CPP:

Провален тест 1:

#include <iostream>
#include <string>
using namespace std;
string s1, s2, s3, s4, s5;
int a;
int fin;

int main()
{
    s2 = "RRGGBB";
    s3 = "rrggbb";
    s4 = "rgb";
    s5 = "RGB";
    cin >> a;
    cin >> s1;
    int cnt1 = 0;
    for (string::size_type i = 0; i < s1.length(); ++i)
        if (s1[i] == s2[0])
            if (s1.substr(i, s2.length()) == s2)
            {
                ++cnt1;
                i += s2.length() - 1;
            }
    int cnt2 = 0;
    
    for (string::size_type i = 0; i < s1.length(); ++i)
        if (s1[i] == s3[0])
            if (s1.substr(i, s2.length()) == s2)
            {
                ++cnt2;
                i += s3.length() - 1;
            }
    int cnt3 = 0;

    for (string::size_type i = 0; i < s1.length(); ++i)
        if (s1[i] == s4[0])
            if (s1.substr(i, s2.length()) == s2)
            {
                ++cnt3;
                i += s4.length() - 1;
            }
    int cnt4 = 0;

    for (string::size_type i = 0; i < s1.length(); ++i)
        if (s1[i] == s5[0])
            if (s1.substr(i, s2.length()) == s2)
            {
                ++cnt4;
                i += s5.length() - 1;
            }
    for (int k = 10; k <= 0; k--) {
        if (cnt1 == k || cnt2 == k) {
            fin = 3 * cnt1;
                if (fin <= 0) { fin = 3 * cnt2; }
        }
        if (fin <= 1) {
            if (cnt3 == k || cnt4 == k) {
                fin = 3 * cnt3;
                    if (fin <= 0) { fin = 3 * cnt4; }
            }
        }
    }
    cout << fin;
}

P.S. Помогли в решении на киберфоруме(https://www.cyberforum.ru/python-tasks/thread3178263.html)

Код:

n = int(input())
s = input()
max_cnt = r = g = b = i = 0
while i < n:
    while i < n and s[i] in ['G', 'B']:
        i += 1
    while i < n and s[i] == 'R':
        r += 1
        i += 1
    while i < n and s[i] == 'G' and r:
        g += 1
        i += 1
    while i < n and s[i] == 'B' and r and g:
        b += 1
        i += 1
    if r and g and b and r >= g <= b:
        max_cnt = max(max_cnt, min(r, g, b) * 3)
    r = g = b = 0
print(max_cnt)

Ответы (2 шт):

Автор решения: Stanislav Volodarskiy

Первая программа для примера "RGB" возвращает единицу. Должно быть три.

Вторая программа для примера "RGBB" возращает ноль. Должно быть три.

Третья программа для примера "RGB" возвращает ноль. Должно быть три.

Конечный автомат поддерживает размеры последних групп из R, G, B. Если порядок нарушился, размеры стираются. В радуге должно быть одинаковое количество всех видов символов. Размер радуги определяется размером группы G. Она должна быть не больше размеров R, B:

input() # skip n
max_g = 0
r = g = b = 0
for c in input():
    if c == 'R':
        if g > 0 or b > 0:
            r = g = b = 0
        r += 1
    if c == 'G':
        if b > 0:
            r = g = b = 0
        g += 1
    if c == 'B':
        b += 1
    if r >= g and b >= g:
        max_g = max(g, max_g)
print(3 * max_g)
→ Ссылка
Автор решения: Harry

Примерно так с ДКА (без учета непонятного "считать он умеет только до двух" — просто максимальная длина подстроки типа R..RG..GB..B):

#include <string>
#include <iostream>

using namespace std;

int new_state[4][3] = {{ 1, 0, 0 },{ 1, 2, 0 },{ 1, 2, 3 },{ 1, 0, 3 }};
int act[4][3]       = {{ 1, 0, 0 },{ 2, 2, 0 },{ 1, 2, 2 },{ 1, 0, 2 }};

int rgb(const char * s)
{
    int maxl = 0, count = 0;
    int state = 0;
    for(const char * c = s; *c; c++)
    {
        int in = (toupper(*c) == 'R') ? 0 : (toupper(*c) == 'G') ? 1 : 2;
        if (state == 3 && (in == 0 || in == 1) && maxl < count) maxl = count;
        if (act[state][in] == 2) count++; else count = act[state][in];
        state = new_state[state][in];
    }
    if (state == 3 && maxl < count) maxl = count;
    return maxl;
}

int main(int argc, char * argv[])
{
    string s;
    cin >> s;
    cout << rgb(s.c_str()) << endl;
}
→ Ссылка