В чём заключается ошибка в работе моего алгоритма? Какие ненужные подстроки он определяет?

Где можно найти задачу под номером 3763, упомянутую <a href="https://kompege.ru/task" rel="nofollow">здесь</a>? <br/> Я попытался объяснить свой алгоритм с помощью комментариев в коде и надеюсь, что их будет достаточно для его понимания. <br/> <pre><code class="cs">using Microsoft.VisualBasic;
using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Net;
using System.Numerics;
using System.Runtime.CompilerServices;
using System.Text;
using System.Text.RegularExpressions;
using System.Xml;
using static System.Math;
using static System.Runtime.InteropServices.JavaScript.JSType;

namespace Solution
{
    class MAIN
    {
        static int ValidSubstringsCount(string input) // Возвращает количество подстрок длиной более 2 символов
        {
            // Кажется, что проблема именно с этим методом, хотя он работает корректно на простых примерах
            int output = 0;
            for (int i = 0, length = input.Length - 2; i < length; i++)
            {
                output += input.Length - 2 - i;
            }
            return output;
        }


        static string LastOneCharSubstring(string input, int end_index) // Возвращает наибольшую подстроку, заканчивающуюся на индексе end_index, состоящую из одинаковых символов (например, LastOneCharSubstring("CAAABC", 3) возвращает "AAA")
        {
            char last_symb = input[end_index];
            int start_index = end_index;
            while (start_index != 0)
            {
                if (input[--start_index] != last_symb) return input.Substring(start_index+1, end_index-start_index);
            }
            return input.Substring(0, end_index + 1);
        }
  • 24 марта 2025 г. 10:25
Ответы на вопрос 2
В вашем коде есть несколько моментов, которые могут быть причиной ошибочного поведения. Давайте разберем оба метода.

### Метод `ValidSubstringsCount`

Этот метод должен возвращать количество подстрок длиной более 2 символов, однако его логика не совсем верна. Давайте разберем ваш текущий алгоритм:

```csharp
for (int i = 0, length = input.Length - 2; i < length; i++)
{
    output += input.Length - 2 - i;
}
```

В этом цикле `output` увеличивается на `input.Length - 2 - i`. Давайте посмотрим, что это значит:

1. `input.Length - 2` — это длина строки минус 2.
2. Вы итерируетесь по индексам `0` до `length`, но только до `input.Length - 3` фактически, так как цикл не инклюзивный для `length`.
3. Получается, что вы считаете подстроки неправильно. Вам нужно что-то более конкретное для подсчета подстрок.

### Исправленный подход

Поскольку мы хотим получить количество подстрок длиной более 2 символов, вы можете использовать формулу:

- Для строки длины `n`, количество подстрок длиной более 2 символов будет равно сумме подстрок длиной 3, 4, ..., n:
  
```csharp
static int ValidSubstringsCount(string input)
{
    int n = input.Length;
    if (n < 3) return 0; // если длина строки меньше 3, подстрок нет.

    // Количество подстрок длиной более 2
    return (n - 2) * (n - 1) / 2; // сумма арифметической прогрессии.
}
```

### Метод `LastOneCharSubstring`

Этот метод выглядит более корректно, но имейте в виду следующее:

- Если переданный `end_index` будет равен `0`, это может вызвать ошибку, так как вы пытаетесь уменьшить `start_index` до -1.
- Также стоит быть внимательным к тому, как вы используете `input.Substring()`, так как если `end_index` равен 0, возврат `input.Substring(0, end_index + 1)` будет корректен, но `input.Substring(0, 1)` или `input.Substring(0, 0)` (если передать `0`), потенциально может быть проблемой.

Вот поправленный вариант метода:

```csharp
static string LastOneCharSubstring(string input, int end_index)
{
    if (end_index < 0 || end_index >= input.Length)
        throw new ArgumentOutOfRangeException("end_index");

    char last_symb = input[end_index];
    int start_index = end_index;

    while (start_index > 0) // изменяем на start_index > 0
    {
        start_index--;
        if (input[start_index] != last_symb) 
        {
            return input.Substring(start_index + 1, end_index - start_index);
        }
    }
    return input.Substring(0, end_index + 1); // корректно работает для всей строки
}
```

### Задача 3763

Что касается задачи под номером 3763, ссылки не переходят напрямую на конкретные задачи в различных сразу нескольких ресурсах, это зависит от платформы. Я бы рекомендовал вам поискать ее на сайте, который вы упоминали, или на специализированных профилирующих ресурсах (например, Codeforces, LeetCode и т.д.), где опубликованы задачи по разным номерам.
Пошаговая отладка вам в помощь.
Похожие вопросы