Técnica de Janela Deslizante para o Problema Complete the Word

O problema "Complete the Word" exige que, dada uma string com letras maiúsculas ou '?' (representando letras desconhecidas), dteermine se é possível substituir os '?' por letras para que a string contenha um substring de comprimento 26 com cada letra do alfabeto aparecendo exatamente uma vez. A técnica de janela deslizante é eficaz para percorreer a string e verificar janelas de tamanho fixo.

Especificação de Entrada e Saída

Entrada: Uma string s (1 ≤ |s| ≤ 50 000) contendo letras maiúsculas ('A'-'Z') e '?'.

Saída: Se não for possível, imprima -1. Caso contrário, imprima uma string válida com todos os '?' substituídos.

Exemplos

Entrada:
ABC??FGHIJK???OPQR?TUVWXY?

Saída:
ABCDEFGHIJKLMNOPQRZTUVWXYS
Entrada:
WELCOMETOCODEFORCESROUNDTHREEHUNDREDANDSEVENTYTWO

Saída:
-1
Entrada:
??????????????????????????

Saída:
MNBVCXZLKJHGFDSAQPWOEIRUYT
Entrada:
AABCDEFGHIJKLMNOPQRSTUVW??M

Saída:
-1

Solução com Técnica de Janela Deslizante

A abordagem consiste em percorrer a string com uma janela deslizante de tamanho 26. Para cada janela, contamos as letras presentes e os '?'. Se a soma de letras únicas (cada uma aparecendo exatamente uma vez) e '?' for igual a 26, a janela é válida. Então, substituímos os '?' pelas letras do alfabeto que ainda não estão presentes na janela. Os '?' restantes fora da janela podem ser preenchidos com qualquer letra, como 'A'.

Implemantação em C++

#include <cstdio>
#include <cstring>

const int MAX_TAM = 50005;
char entrada[MAX_TAM];
int contador[26];

int main() {
    while (scanf("%s", entrada) != EOF) {
        bool encontrado = false;
        int tamanho = strlen(entrada);
        if (tamanho < 26) {
            printf("-1\n");
            continue;
        }

        for (int i = 0; i <= tamanho - 26 && !encontrado; i++) {
            int letrasUnicas = 0, perguntas = 0;
            memset(contador, 0, sizeof(contador));

            for (int j = i; j < i + 26; j++) {
                if (entrada[j] >= 'A' && entrada[j] <= 'Z') {
                    contador[entrada[j] - 'A']++;
                } else {
                    perguntas++;
                }
            }

            for (int j = 0; j < 26; j++) {
                if (contador[j] == 1) letrasUnicas++;
            }

            if (letrasUnicas + perguntas == 26) {
                int proxLetra = 0;
                for (int j = i; j < i + 26; j++) {
                    if (entrada[j] == '?') {
                        while (proxLetra < 26) {
                            if (contador[proxLetra] == 0) {
                                entrada[j] = 'A' + proxLetra;
                                proxLetra++;
                                break;
                            }
                            proxLetra++;
                        }
                    }
                }
                encontrado = true;
            }
        }

        for (int i = 0; i < tamanho; i++) {
            if (entrada[i] == '?') {
                entrada[i] = 'A';
            }
        }

        if (encontrado) {
            printf("%s\n", entrada);
        } else {
            printf("-1\n");
        }
    }
    return 0;
}

Tags: C++ sliding window algorithm string processing Codeforces algorithms

Publicado em 7-11 01:43