Soluciones al Concurso Principiante de AtCoder 335

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.

  1. Convertir el grafo dirigido en no dirigido.
  2. Cada borde va desde un nodo con valor menor a uno con valor mayor (si a[u] > a[v], entonces v → u).
  3. Si a[u] == a[v], unir los nodos en un conjunto disjunto usando Union-Find.
  4. Después de construir el grafo, aplicar programación dinámica en orden topológico para calcular la solución.
  5. 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;
}

Etiquetas: atcoder C++ programación dinámica union-find grafos

Publicado el 6-30 06:11