Problema A: Conversão para Maiúsculas
O desafio conisste em receber uma string composta por letras minúsculas e transformá-la integralmente em letras maiúsculas. Em C++, isso pode ser resolvido iterando sobre a string e utilizando a função toupper() ou manipulando diretamente os valores ASCII.
#include <iostream>
#include <string>
#include <cctype>
using namespace std;
void process_uppercase() {
string texto;
cin >> texto;
for (char &caractere : texto) {
caractere = toupper(caractere);
}
cout << texto << endl;
}
int main() {
process_uppercase();
return 0;
}
Problema B: Controle de Cartões em Partida de Futebol
Neste problema, devemos gerenciar o estado de jogadores com base em cartões amarelos e vermelhos. As regras são simples: um cartão vermelho expulsa o jogador imediatamente, enquanto dois cartões amarelos acumulam o mesmo efeito. Utilizamos um vetor para rastrear a "pontuação de penalidade" de cada jogador.
#include <iostream>
#include <vector>
using namespace std;
void monitor_penalties() {
int total_jogadores, total_eventos;
cin >> total_jogadores >> total_eventos;
vector<int> status(total_jogadores + 1, 0);
while (total_eventos--) {
int tipo, id;
cin >> tipo >> id;
if (tipo == 1) {
status[id] += 1;
} else if (tipo == 2) {
status[id] += 2;
} else {
if (status[id] >= 2) cout << "Yes" << endl;
else cout << "No" << endl;
}
}
}
int main() {
monitor_penalties();
return 0;
}
Problema C: Decomposição de Inteiros AB + CD = N
O objetivo é encontrar o número de quádruplas $(A, B, C, D)$ tais que $A \times B + C \times D = N$. A estratégia otimizada envolve pré-processar a quantidade de divisores para cada número até $N$. Se $X = A \times B$, o número de pares $(A, B)$ é igual ao número de divisores de $X$.
#include <iostream>
#include <vector>
using namespace std;
typedef long long ll;
void count_quadruplets() {
int n;
cin >> n;
vector<ll> divisores(n + 1, 0);
for (int i = 1; i <= n; ++i) {
for (int j = 1; i * j <= n; ++j) {
divisores[i * j]++;
}
}
ll total_combinacoes = 0;
for (int k = 1; k < n; ++k) {
total_combinacoes += (divisores[k] * divisores[n - k]);
}
cout << total_combinacoes << endl;
}
int main() {
count_quadruplets();
return 0;
}
Problema D: Verificação de Componentes Unicíclicos
Neste cenário, um grafo é dado e precisamos veriifcar se, em cada componente conexo, o número de vértices é exatamente igual ao número de arestas. A estrutura de dados Disjoint Set Union (DSU) é ideal para agrupar os componentes e contabilizar as propriedades de cada um.
#include <iostream>
#include <vector>
#include <numeric>
using namespace std;
struct DSU {
vector<int> pai;
vector<int> v_cnt, e_cnt;
DSU(int n) {
pai.resize(n + 1);
iota(pai.begin(), pai.end(), 0);
v_cnt.assign(n + 1, 1);
e_cnt.assign(n + 1, 0);
}
int buscar(int i) {
if (pai[i] == i) return i;
return pai[i] = buscar(pai[i]);
}
void unir(int i, int j) {
int raiz_i = buscar(i);
int raiz_j = buscar(j);
if (raiz_i != raiz_j) {
pai[raiz_i] = raiz_j;
v_cnt[raiz_j] += v_cnt[raiz_i];
e_cnt[raiz_j] += e_cnt[raiz_i] + 1;
} else {
e_cnt[raiz_i]++;
}
}
};
int main() {
int n, m;
cin >> n >> m;
DSU dsu(n);
for (int i = 0; i < m; ++i) {
int u, v;
cin >> u >> v;
dsu.unir(u, v);
}
bool valido = true;
for (int i = 1; i <= n; ++i) {
if (dsu.pai[i] == i) {
if (dsu.v_cnt[i] != dsu.e_cnt[i]) {
valido = false;
break;
}
}
}
cout << (valido ? "Yes" : "No") << endl;
return 0;
}
Problema E: Adição de Arestas para Transitividade
O problema pede para encontrar quantas arestas direcionadas podem ser adicionadas de modo que, se houver um caminho entre $u$ e $v$, exista uma aresta direta $u \to v$. O resultado final é a soma de todos os nós alcançáveis a partir de cada nó (excluindo o próprio nó), subtraindo o número de arestas originais.
#include <iostream>
#include <vector>
#include <queue>
using namespace std;
int calcular_alcancaveis(int inicial, int n, const vector<vector<int>>& adj) {
vector<bool> visitado(n + 1, false);
queue<int> fila;
fila.push(inicial);
visitado[inicial] = true;
int contador = 0;
while (!fila.empty()) {
int atual = fila.front();
fila.pop();
for (int vizinho : adj[atual]) {
if (!visitado[vizinho]) {
visitado[vizinho] = true;
contador++;
fila.push(vizinho);
}
}
}
return contador;
}
int main() {
int n, m;
cin >> n >> m;
vector<vector<int>> adj(n + 1);
for (int i = 0; i < m; ++i) {
int u, v;
cin >> u >> v;
adj[u].push_back(v);
}
long long total_pares = 0;
for (int i = 1; i <= n; ++i) {
total_pares += calcular_alcancaveis(i, n, adj);
}
cout << total_pares - m << endl;
return 0;
}