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;
}