Soluciones de problemas de algoritmia competitiva: simulación, ordenamiento y técnica de dos punteros

Problema A: Reemplazo de caracteres en una cadena

Dada una cadena de longitud N compuesta por letras minúsculas, se debe reemplazar todo carácter que no sea igual a un carácter específico c₁ por otro carácter c₂.

Enfoque: Recorer cada posición de la cadena y aplicar la sustitución de forma directa.

#include <bits/stdc++.h>
using namespace std;

int main() {
    int longitud;
    char mantener, reemplazo;
    string texto;
    cin >> longitud >> mantener >> reemplazo >> texto;
    string resultado;
    for (char ch : texto) {
        resultado += (ch == mantener) ? mantener : reemplazo;
    }
    cout << resultado << endl;
    return 0;
}

Problema B: Actualización de rating por división

Existen competiciones divididas en dos categorías. En la División 1, los participantes con rating entre 1600 y 2799 (inclusive) reciben actualización. En la División 2, los participantes con rating entre 1200 y 2399 (inclusive) la reciben. Se debe simular el cambio de rating a lo largo de N competiciones.

Enfoque: Mantener una variable de rating e iterar sobre cada competición, verificando si el rating actual cae dentro del rango correspondiente a la división de esa competición.

#include <bits/stdc++.h>
using namespace std;

int main() {
    int totalCompes;
    long long rating;
    cin >> totalCompes >> rating;
    for (int i = 0; i < totalCompes; i++) {
        int division, performance;
        cin >> division >> performance;
        if (division == 1 && rating >= 1600 && rating <= 2799) {
            rating += performance;
        } else if (division == 2 && rating >= 1200 && rating <= 2399) {
            rating += performance;
        }
    }
    cout << rating << endl;
    return 0;
}

Problema C: Ranking de participantes por puntuación

Hay 31 participantes, cada uno identificado por una subsecuencia no vacía de la cadena "ABCDE". Cada participante resuelve exactamente los problmeas indicados por las letras de su identificador. Se debe imprimir el ranking ordenado por puntuación descendente, y en caso de empate, por orden lexicográfico ascendente.

Enfoque: Generar todas las 31 subsecuencias no vacías mediante recursión o iteración binaria, calcular la puntuación de cada una, almacenarlas en una estructura con puntuación y nombre, y ordenar.

#include <bits/stdc++.h>
using namespace std;

int puntajes[5];

struct Participante {
    int puntos;
    string nombre;
};

void generar(vector<Participante>& lista, string actual, int puntos, int idx) {
    if (idx == 5) {
        if (!actual.empty()) lista.push_back({-puntos, actual});
        return;
    }
    generar(lista, actual, puntos, idx + 1);
    generar(lista, actual + (char)('A' + idx), puntos + puntajes[idx], idx + 1);
}

int main() {
    for (int i = 0; i < 5; i++) cin >> puntajes[i];
    vector<Participante> lista;
    generar(lista, "", 0, 0);
    sort(lista.begin(), lista.end(), [](const Participante& a, const Participante& b) {
        if (a.puntos != b.puntos) return a.puntos < b.puntos;
        return a.nombre < b.nombre;
    });
    for (auto& p : lista) cout << p.nombre << endl;
    return 0;
}

Problema D: Subsecuencia con suma objetivo en secuencia periódica

Se tiene una secuencia infinita con período N, donde los primeros N elementos definen el patrón que se repite. Se debe determinar si existe un subarreglo contiguo no vacío cuya suma sea exactamente S.

Enfoque: Primero reducir S módulo la suma total del período. Luego duplicar el arreglo para simular la circularidad y aplicar la técnica de dos punteros, aprovechando la monotonicidad de las sumas parciales prefix.

#include <bits/stdc++.h>
using namespace std;

int main() {
    int n;
    long long objetivo;
    cin >> n >> objetivo;
    vector<long long> valores(2 * n);
    long long sumaPeriodo = 0;
    for (int i = 0; i < n; i++) {
        cin >> valores[i];
        sumaPeriodo += valores[i];
        valores[i + n] = valores[i];
    }
    objetivo %= sumaPeriodo;
    if (objetivo == 0) {
        cout << "Yes" << endl;
        return 0;
    }
    vector<long long> pref(2 * n + 1, 0);
    for (int i = 0; i < 2 * n; i++) pref[i + 1] = pref[i] + valores[i];
    int izq = 0, der = 0;
    while (izq < 2 * n) {
        while (der < 2 * n && pref[der + 1] - pref[izq] < objetivo) der++;
        if (der < 2 * n && pref[der + 1] - pref[izq] == objetivo) {
            cout << "Yes" << endl;
            return 0;
        }
        izq++;
    }
    cout << "No" << endl;
    return 0;
}

Etiquetas: atcoder algoritmos C++ Simulación Dos punteros

Publicado el 7-13 03:58