Problema A: Cammbiar el último carácter
Modificar el último carácter de una cadena de entrada a '4'.
#include <bits/stdc++.h>
using namespace std;
void resolver() {
string entrada;
cin >> entrada;
entrada.back() = '4';
cout << entrada << endl;
}
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
resolver();
return 0;
}
Problema B: Númeero tetraédrico
Generar todas las ternas de enteros no negativos (x, y, z) tales que x + y + z sea menor o igual que un valor n dado.
#include <bits/stdc++.h>
using namespace std;
void resolver() {
int n;
cin >> n;
for (int x = 0; x <= n; x++) {
for (int y = 0; y <= n; y++) {
for (int z = 0; z <= n; z++) {
if (x + y + z <= n) {
cout << x << " " << y << " " << z << endl;
}
}
}
}
}
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
resolver();
return 0;
}
Problema C: Seguimiento de loong
Utilizar una deque para rastrear las posiciones de una serpiente, actualizando según comandos de movimiento y consultando posiciones por índice.
#include <bits/stdc++.h>
using namespace std;
void resolver() {
int n, q;
cin >> n >> q;
deque<pair<int, int>> trayectoria;
for (int i = 1; i <= n; i++) {
trayectoria.push_back({i, 0});
}
while (q--) {
int tipo;
cin >> tipo;
if (tipo == 1) {
char dir;
cin >> dir;
int u = trayectoria[0].first;
int v = trayectoria[0].second;
if (dir == 'U') trayectoria.push_front({u, v + 1});
else if (dir == 'D') trayectoria.push_front({u, v - 1});
else if (dir == 'L') trayectoria.push_front({u - 1, v});
else if (dir == 'R') trayectoria.push_front({u + 1, v});
trayectoria.pop_back();
} else {
int y;
cin >> y;
cout << trayectoria[y - 1].first << " " << trayectoria[y - 1].second << endl;
}
}
}
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
resolver();
return 0;
}
Problema D: Loong y Takahashi
Rellenar un tablero cuadrado de tamaño n en espiral, numerando las casillas secuencialmente, y marcar la posición central con 'T'.
#include <bits/stdc++.h>
using namespace std;
int tablero[100][100];
void resolver() {
int n;
cin >> n;
memset(tablero, 0, sizeof(tablero));
int x = 0, y = 1;
int contador = 0;
while (contador < n * n) {
while (x + 1 <= n && tablero[x + 1][y] == 0) tablero[++x][y] = ++contador;
while (y + 1 <= n && tablero[x][y + 1] == 0) tablero[x][++y] = ++contador;
while (x - 1 > 0 && tablero[x - 1][y] == 0) tablero[--x][y] = ++contador;
while (y - 1 > 0 && tablero[x][y - 1] == 0) tablero[x][--y] = ++contador;
}
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= n; j++) {
if ((n + 1) / 2 == i && i == j) cout << "T ";
else cout << tablero[i][j] << " ";
}
cout << endl;
}
}
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
resolver();
return 0;
}
Problema E: Camino colorido no decreciente
Encontrar la longitud del camino más largo en un grafo donde los nodos tienen valores y los bordes deben seguir un orden no decreciente. Se usa Union-Find para fusionar nodos con valores iguales y programación dinámica en orden topológico basado en los valores.
- Convertir el grafo dirigido en no dirigido.
- Cada borde va desde un nodo con valor menor a uno con valor mayor (si a[u] > a[v], entonces v → u).
- Si a[u] == a[v], unir los nodos en un conjunto disjunto usando Union-Find.
- Después de construir el grafo, aplicar programación dinámica en orden topológico para calcular la solución.
- Ordenar los nodos por valor ascendente para obtener el orden topológico.
#include <bits/stdc++.h>
using namespace std;
const int N = 2e5 + 10;
vector<int> adyacente[N];
int valor[N], padre[N], camino[N];
int Find(int x) {
return x == padre[x] ? x : padre[x] = Find(padre[x]);
}
void resolver() {
int n, m;
cin >> n >> m;
vector<int> nodos;
for (int i = 1; i <= n; i++) {
cin >> valor[i];
padre[i] = i;
camino[i] = -999999999;
nodos.push_back(i);
}
for (int i = 1; i <= m; i++) {
int u, v;
cin >> u >> v;
if (valor[u] == valor[v]) {
int raiz_u = Find(u);
int raiz_v = Find(v);
padre[raiz_u] = raiz_v;
} else {
if (valor[u] > valor[v]) swap(u, v);
adyacente[u].push_back(v);
}
}
camino[Find(1)] = 1;
sort(nodos.begin(), nodos.end(), [](int x, int y) { return valor[x] < valor[y]; });
for (auto u : nodos) {
for (auto v : adyacente[u]) {
camino[Find(v)] = max(camino[Find(v)], camino[Find(u)] + 1);
}
}
cout << max(camino[Find(n)], 0) << endl;
}
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
resolver();
return 0;
}
Problema F: Hop Sugoroku
Calcular el número de formas de alcanzar el final de un tablero lineal con saltos de longitudes variables, usando descomposición por raíz cuadrada y programación dinámica para optimizar el tiempo.
#include <bits/stdc++.h>
using namespace std;
const int N = 2e5 + 10, M = 500;
const int MOD = 998244353;
int pasos[N], resto[M][M], formas[N];
void resolver() {
int n;
cin >> n;
for (int i = 1; i <= n; i++) cin >> pasos[i];
long long total = 0;
formas[1] = 1;
for (int i = 1; i <= n; i++) {
for (int j = 1; j < M; j++) {
formas[i] = (formas[i] + resto[i % j][j]) % MOD;
}
if (pasos[i] >= M) {
for (int j = i + pasos[i]; j <= n; j += pasos[i]) {
formas[j] = (formas[j] + formas[i]) % MOD;
}
} else {
resto[i % pasos[i]][pasos[i]] = (resto[i % pasos[i]][pasos[i]] + formas[i]) % MOD;
}
total = (total + formas[i]) % MOD;
}
cout << total << endl;
}
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
resolver();
return 0;
}