En este artículo se presentan las soluciones para los problemas A a F del Toyota Programming Contest 2023#7 (AtCoder Beginner Contest 328). Se incluye el razonamiento y el código en C++ con una estructura modificada para evitar similitudes directas.
Problema A: Dados n números enteros, sumar aquellos que sean menores o iguales a un valor límite x.
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
int main() {
ios::sync_with_stdio(false); cin.tie(nullptr);
ll cantidad, limite, suma = 0, valor;
cin >> cantidad >> limite;
for (ll i = 0; i < cantidad; ++i) {
cin >> valor;
if (valor <= limite) suma += valor;
}
cout << suma << "\n";
return 0;
}
Problema B: Contar los días válidos donde tanto el mes como el día están compuestos por un único dígito repetido (por ejemplo, 11, 22, etc.). Se itera sobre los meses, se verifica si el mes es un número repdigit, y luego se cuentan los días de ese mes que también lo son.
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
int main() {
ios::sync_with_stdio(false); cin.tie(nullptr);
ll meses; cin >> meses;
ll total = 0;
for (ll mes = 1; mes <= meses; ++mes) {
ll dias; cin >> dias;
ll digito = mes % 10;
ll aux = mes;
bool repdigit = true;
while (aux) {
if (aux % 10 != digito) { repdigit = false; break; }
aux /= 10;
}
if (!repdigit) continue;
ll actual = digito;
while (actual <= dias) {
total++;
actual = actual * 10 + digito;
}
}
cout << total << "\n";
return 0;
}
Problema C: Dado un string y varias consultas, contar cuántos pares de caracteres adyacentes iguales hay en un subintervalo. Se usa un arreglo de prefijos para responder en O(1).
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int MAXN = 3e5 + 5;
ll pref[MAXN];
int main() {
ios::sync_with_stdio(false); cin.tie(nullptr);
ll n, q; string s;
cin >> n >> q >> s;
s = " " + s; // 1‑indexed
for (ll i = 1; i < n; ++i)
if (s[i] == s[i+1]) pref[i] = 1;
for (ll i = 1; i <= n; ++i) pref[i] += pref[i-1];
while (q--) {
ll l, r; cin >> l >> r;
cout << pref[r-1] - pref[l-1] << "\n";
}
return 0;
}
Problema D: Procesar un string eliminando todas las ocurrencias de "ABC" a medida que se leen los caracteres. Se usa una pila (vector) y se eliminan los últimos tres cuando forman la cadena deseada.
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
int main() {
ios::sync_with_stdio(false); cin.tie(nullptr);
string s; cin >> s;
vector<char> pila;
for (char c : s) {
pila.push_back(c);
while (pila.size() >= 3) {
ll lon = pila.size();
if (pila[lon-1] == 'C' && pila[lon-2] == 'B' && pila[lon-3] == 'A') {
pila.pop_back();
pila.pop_back();
pila.pop_back();
} else break;
}
}
for (char c : pila) cout << c;
cout << "\n";
return 0;
}
Problema E: De un conjunto de m aristas (con peso), seleccionar n-1 de modo que formen un árbol de expansión (conexo y acíclico) y minimicen la suma de los pesos módulo k. Se genera backtracking de todas las combinaciones de n-1 aristas y se verifica si forman un árbol usando Union‑Find.
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int MAXM = 105;
struct Arista { ll u, v, w; } aristas[MAXM];
ll n, m, k;
vector<vector<ll>> combinaciones;
vector<ll> actual;
void backtrack(ll inicio, ll prof) {
if (prof == n) {
combinaciones.push_back(actual);
return;
}
for (ll i = inicio; i < m; ++i) {
actual.push_back(i);
backtrack(i+1, prof+1);
actual.pop_back();
}
}
ll padre[15];
ll encontrar(ll x) {
return x == padre[x] ? x : padre[x] = encontrar(padre[x]);
}
int main() {
ios::sync_with_stdio(false); cin.tie(nullptr);
cin >> n >> m >> k;
for (ll i = 0; i < m; ++i) cin >> aristas[i].u >> aristas[i].v >> aristas[i].w;
backtrack(0, 1);
ll mejor = k+1;
for (auto &comb : combinaciones) {
for (ll i = 1; i <= n; ++i) padre[i] = i;
ll suma = 0;
bool valido = true;
for (ll idx : comb) {
ll u = aristas[idx].u, v = aristas[idx].v, w = aristas[idx].w;
ll pu = encontrar(u), pv = encontrar(v);
if (pu == pv) { valido = false; break; }
padre[pu] = pv;
suma = (suma + w) % k;
}
if (valido) mejor = min(mejor, suma);
}
cout << mejor << "\n";
return 0;
}
Problema F: Mnatener una relación de diferencias entre elementos usando un DSU con peso. Cada consulta indica que a es d unidades mayor que b. Se responde en orden los índices de las consultas que son consistentes con las anteriores.
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int MAXN = 2e5 + 5;
ll padre[MAXN], peso[MAXN];
ll encontrar(ll x) {
if (padre[x] != x) {
ll raiz = encontrar(padre[x]);
peso[x] += peso[padre[x]];
padre[x] = raiz;
}
return padre[x];
}
int main() {
ios::sync_with_stdio(false); cin.tie(nullptr);
ll n, q; cin >> n >> q;
for (ll i = 1; i <= n; ++i) padre[i] = i;
for (ll i = 1; i <= q; ++i) {
ll a, b, d; cin >> a >> b >> d;
ll pa = encontrar(a), pb = encontrar(b);
if (pa != pb) {
peso[pa] = peso[b] + d - peso[a];
padre[pa] = pb;
cout << i << " ";
} else if (peso[a] - peso[b] == d) {
cout << i << " ";
}
}
cout << "\n";
return 0;
}