Soluções de Programação Competitiva: Análise de Problemas do Round 3

Este é um problema baseado em padrões. O volume total de água é calculado como b multiplicado por n. Se este total for menor ou igual à capacidade a de um recipiente, a resposta é o próprio volume total. Caso contrário, como a água não pode transbordar, a solução é subtrair o excesso, resultando em a - (a % b), que representa o maior múltiplo de b que cabe em a.


#include <iostream>
using namespace std;

int main() {
    long long capacidade, volume_unitario, unidades;
    cin >> capacidade >> volume_unitario >> unidades;
    long long agua_total = volume_unitario * unidades;

    if (agua_total <= capacidade) {
        cout << agua_total;
    } else {
        cout << capacidade - (capacidade % volume_unitario);
    }

    return 0;
}

Problema T2

Para tornar dois segmentos de reta intersectantes, no máximo duas operações de translação são necessárias: uma vertical e uma horizontal. A necessidade de translação vertical é determinada pela sobreposição dos intervalos de coordenadas x dos segmentos. Se não houver sobreposição, uma operação vertical é requerida. Analogamente, para translação horizontal, verificam-se os intervalos de coordenadas y.


#include <iostream>
#include <algorithm>
using namespace std;

int main() {
    int testes;
    cin >> testes;

    while (testes--) {
        long long x1_ini, y1_ini, x1_fim, y1_fim;
        long long x2_ini, y2_ini, x2_fim, y2_fim;
        cin >> x1_ini >> y1_ini >> x1_fim >> y1_fim >> x2_ini >> y2_ini >> x2_fim >> y2_fim;

        int operacoes = 0;

        if (max(x1_ini, x1_fim) < min(x2_ini, x2_fim) || min(x1_ini, x1_fim) > max(x2_ini, x2_fim)) {
            operacoes++;
        }

        if (max(y1_ini, y1_fim) < min(y2_ini, y2_fim) || min(y1_ini, y1_fim) > max(y2_ini, y2_fim)) {
            operacoes++;
        }

        cout << operacoes << endl;
    }

    return 0;
}

Problema T3

Este problema envolve operações de inversão em uma string circular. Inverter um número par de vezes não altera o resultado, então consideramos apenas inversões ímpares. Rastreamos uma posição inicial x (base 1). Para operações de deslocamento à direita ("> s"), adicionamos s a x, e para esquerda ("< s"), subtraímos s, ajustando com módulo para manter a circularidade. Após processar todas as operações, reconstruímos a string com base na contagem de inversões.


#include <iostream>
#include <string>
#include <algorithm>
using namespace std;

int main() {
    string texto;
    cin >> texto;
    int comprimento = texto.size();
    int operacoes;
    cin >> operacoes;

    int inversoes = 0;
    int posicao = 1;

    for (int i = 0; i < operacoes; ++i) {
        string op;
        cin >> op;

        if (op == "rev") {
            inversoes++;
            posicao = comprimento - posicao + 1;
        } else if (op == ">") {
            int desloc;
            cin >> desloc;
            desloc %= comprimento;
            posicao += desloc;
            if (posicao > comprimento) posicao %= comprimento;
        } else if (op == "<") {
            int desloc;
            cin >> desloc;
            desloc %= comprimento;
            posicao = (posicao - desloc + comprimento) % comprimento;
        }
    }

    string resultado;
    if (inversoes % 2 == 1) {
        string parte1 = texto.substr(posicao - 1, comprimento - posicao + 1);
        string parte2 = texto.substr(0, posicao - 1);
        reverse(parte1.begin(), parte1.end());
        reverse(parte2.begin(), parte2.end());
        resultado = parte2 + parte1;
    } else {
        string parte1 = texto.substr(posicao - 1, comprimento - posicao + 1);
        string parte2 = texto.substr(0, posicao - 1);
        resultado = parte1 + parte2;
    }

    cout << resultado << endl;
    return 0;
}

Problema T4

Dada uma sequência a, encontrar k subsequências contíguas de mesmo comprimento L, tal que a amplitude (diferença entre máximo e mínimo) da menor entre elas seja maximizada. Resolver o valor máximo da amplitude e o menor L possível. A solução utiliza busca binária para L e uma tabela ST (Sparse Tible) para consultas de máximo e mínimo em intervalos, garantindo eficiência temporal.


#include <iostream>
#include <cmath>
#include <algorithm>
using namespace std;

const int MAX_N = 100005;
int n, k;
int seq[MAX_N];
int tabela_max[MAX_N][20], tabela_min[MAX_N][20];
int logaritmo[MAX_N];

void precomputar() {
    logaritmo[1] = 0;
    for (int i = 2; i <= n; i++) {
        logaritmo[i] = logaritmo[i >> 1] + 1;
    }

    for (int i = 1; i <= n; i++) {
        tabela_max[i][0] = tabela_min[i][0] = seq[i];
    }

    for (int j = 1; (1 << j) <= n; j++) {
        for (int i = 1; i + (1 << j) - 1 <= n; i++) {
            tabela_max[i][j] = max(tabela_max[i][j-1], tabela_max[i + (1 << (j-1))][j-1]);
            tabela_min[i][j] = min(tabela_min[i][j-1], tabela_min[i + (1 << (j-1))][j-1]);
        }
    }
}

int consultar_intervalo(int l, int r) {
    int tamanho = r - l + 1;
    int p = logaritmo[tamanho];
    int valor_max = max(tabela_max[l][p], tabela_max[r - (1 << p) + 1][p]);
    int valor_min = min(tabela_min[l][p], tabela_min[r - (1 << p) + 1][p]);
    return valor_max - valor_min;
}

int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);

    int testes;
    cin >> testes;
    while (testes--) {
        cin >> n >> k;
        for (int i = 1; i <= n; i++) {
            cin >> seq[i];
        }

        precomputar();

        int amplitude_maxima = 0;
        for (int i = 1; i <= k; i++) {
            int amp = consultar_intervalo(i, i + (n - k + 1) - 1);
            amplitude_maxima = max(amplitude_maxima, amp);
        }

        int baixo = 1, alto = n - k + 1, comprimento_ans = alto;
        while (baixo <= alto) {
            int meio = (baixo + alto) / 2;
            int amplitude_minima = 1e9;
            for (int i = 1; i + meio - 1 <= n; i++) {
                int amp = consultar_intervalo(i, i + meio - 1);
                amplitude_minima = min(amplitude_minima, amp);
            }

            if (amplitude_minima == amplitude_maxima) {
                comprimento_ans = meio;
                alto = meio - 1;
            } else {
                baixo = meio + 1;
            }
        }

        cout << amplitude_maxima << " " << comprimento_ans << endl;
    }

    return 0;
}

Tags: C++ busca binária ST table Programação Competitiva algoritmos de otimização

Publicado em 7-10 22:19